如何使用PHP在DOMElements上执行XPath查询?

时间:2011-05-08 18:07:50

标签: php dom xpath element

我正在尝试对DOMElements进行Xpath查询,但它似乎不起作用。这是代码

<html>
    <div class="test aaa">
        <div></div>
        <div class="link">contains a link</div>
        <div></div>
    </div>
    <div class="test bbb">
        <div></div>
        <div></div>
        <div class="link">contains a link</div>
    </div>
</html>

我正在做的是:

$dom = new DOMDocument();
$html = file_get_contents("file.html");
@$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$entries = $xpath->query("//div[contains(@class,'test')]");
if (!$entries->length > 0) {
    echo "Nothing\n";
} else {
  foreach ($entries as $entry) {
      $link = $xpath->query('/div[@class=link]',$entry);
      echo $link->item(0)->nodeValue;
      // => PHP Notice:  Trying to get property of non-object
  }
}

一切正常$xpath->query('/div[@class=link], $entry);。我不知道如何在特定的DOMElement($ entry)上使用Xpath。

如何在DOMElement上使用xpath查询?

1 个答案:

答案 0 :(得分:7)

看起来你正在尝试将CS​​S选择器与XPath混合使用。您希望使用谓词([...])查看class属性的值。

例如,您的//div.link可能看起来像//div[contains(concat(' ',normalize-space(@class),' '),' link ')]

其次,在循环中,您尝试使用上下文节点进行查询,然后通过使用绝对位置路径(以斜杠开头)忽略它。

更新以反映问题的变化:

您的第二个XPath表达式(/div[@class=link])仍然是a)绝对值,并且b)具有不正确的条件。您希望请求相对于指定上下文节点($entry)的匹配元素,其中class属性的字符串值link

所以/div[@class=link]应该变成类似div[@class="link"]的内容,用于搜索$entry元素的子项(如果您想更深入地搜索,请使用.//div[...]descendant::div[...]