如何使用 PHP 对 DOMElements 执行 XPath 查询?
我正在尝试对 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 查询?
I'm trying to do Xpath queries on DOMElements but it doesn't seem to work. Here is the code
<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>
What I'm doing is this:
$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
}
}
Everything works fine up to $xpath->query('/div[@class=link], $entry);
. I don't know how to use Xpath on a particular DOMElement ($entry).
How can I use xpath queries on DOMElement?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看起来您正在尝试将 CSS 选择器与 XPath 混合使用。您希望使用谓词 (
[...]
) 查看class
属性的值。例如,您的
//div.link
可能看起来像//div[contains(concat(' ',normalize-space(@class),' '),' link ')]
。其次,在循环中,您尝试使用上下文节点进行查询,然后使用绝对位置路径(以斜杠开头)忽略该查询。
更新以反映问题的更改:
您的第二个 XPath 表达式 (
/div[@class=link]
) 仍然是 a) 绝对表达式,并且 b) 条件不正确。您想要请求相对于指定上下文节点 ($entry
) 的匹配元素,其中class
属性的字符串值为链接。
因此
/div[@class=link]
应该变成类似div[@class="link"]
的东西,它搜索$entry
元素(如果您想更深入地搜索,请使用.//div[...]
或descendant::div[...]
)。It looks like you're trying to mix CSS selectors with XPath. You want to be using a predicate (
[...]
) looking at the value of theclass
attribute.For example, your
//div.link
might look like//div[contains(concat(' ',normalize-space(@class),' '),' link ')]
.Secondly, within the loop you try to make a query with a context node then ignore that by using an absolute location path (it starts with a slash).
Updated to reflect changes to the question:
Your second XPath expression (
/div[@class=link]
) is still a) absolute, and b) has an incorrect condition. You want to be asking for matching elements relative to the specified context node ($entry
) with theclass
attribute having a string value oflink
.So
/div[@class=link]
should become something likediv[@class="link"]
, which searches children of the$entry
elements (use.//div[...]
ordescendant::div[...]
if you want to search deeper).