2

我正在尝试从特定节点的父节点获取文本。例如:

<td colspan="1" rowspan="1">
  <span>
    <a class="info" shape="rect" 
             rel="empLinkData" href="/employee.htm?id=8468524">
        Jack Johnson
    </a>
  </span>
   (*)&nbsp;
</td>

我可以使用以下方法成功处理锚标记:

$xNodes = $xpath->query('//a[@class="info"][@rel="empLinkData"]');

// $xNodes contains employee ids and names
foreach ($xNodes as $xNode)
{
    $sLinktext = @$xNode->firstChild->data;
    $sLinkurl = 'http://www.company.com' . $xNode->getAttribute('href');

    if ($sLinktext != '' && $sLinkurl != '')
    {
        echo '<li><a href="' . $sLinkurl . '">' .
                $sLinktext . '</a></li>';
    }
}

现在,我需要从<td>标签中检索文本(在这种情况下,(*)&nbsp;在 span 标签关闭后立即出现),但我似乎无法正确引用它。

对我来说似乎最有意义的 xpath 是:

$xNodes = $xpath->query('//a[@class="info"]
          [@rel="empLinkData"]/ancestor::*');

但它正在从嵌套在此代码上方的其他地方检索错误的数据。

4

3 回答 3

2

没有必要退回到树上。相反,直接选择td包含相关元素的:

//td[descendant::a[@class="info"][@rel="empLinkData"]]/text()

编辑:正如@Dimitre 正确指出的那样,这会选择所有文本子项。你td有两个这样的节点:前面的纯空格文本节点和后面的span文本节点。如果您只想要第二个文本节点,请使用:

//td[descendant::a[@class="info"][@rel="empLinkData"]]/text()[2]

或者:

//td[descendant::a[@class="info"][@rel="empLinkData"]]/text()[last()]

如您所见,生成的表达式基本相同,但您确实需要定位正确的文本节点(如果您只想要一个)。另请注意,如果目标文本确实在 a 中,td那么直接定位该元素类型(不带通配符)会更安全。由于这是 HTML,您的实际文档几乎肯定包含其他几个元素,包括您可能不想定位的多个其他锚点。

示例 PHP:

$nodes = $xpath->query(
    '//td[descendant::a[@class="info"][@rel="empLinkData"]]/text()[last()]');
echo "[". $nodes->item(0)->nodeValue . "]";
于 2012-07-08T22:51:06.033 回答
0

最深的 td 祖先:

//a[@class="info"][@rel="empLinkData"]/ancestor::td[1]
于 2012-07-08T22:42:48.453 回答
0

使用

//*[a[@class="info"][@rel="empLinkData"]]/following-sibling::text()[1]

这会选择一个文本节点——正是想要的。

请注意 XPath 表达式,如

//td[descendant::a[@class="info"][@rel="empLinkData"]]/text() 

选择多个文本节点——不仅是想要的文本节点。

于 2012-07-08T23:52:55.690 回答