XPath - 使用php xpath从父级获取文本

时间:2012-07-08 22:35:17

标签: php html xml xpath

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

<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>标记中检索文本(在这种情况下,在{span}标记关闭后出现(*)&nbsp;),但我似乎无法参考它正确。

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

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

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

3 个答案:

答案 0 :(得分: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()]

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

示例PHP:

$nodes = $xpath->query(
    '//td[descendant::a[@class="info"][@rel="empLinkData"]]/text()[last()]');
echo "[". $nodes->item(0)->nodeValue . "]";

答案 1 :(得分:0)

最深的td祖先:

//a[@class="info"][@rel="empLinkData"]/ancestor::td[1]

答案 2 :(得分:0)

使用

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

这将选择一个文本节点 - 正好是所需的文本节点。

请注意XPath表达式,如

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

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