php 如何在 DOMNode 上执行 XPath 查询?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16727378/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I do an XPath query on a DOMNode?
提问by developarvin
Is there a way to do an xpath query on a DOMNode? Or at least convert it to a DOMXPath?
有没有办法在 DOMNode 上执行 xpath 查询?或者至少将其转换为 DOMXPath?
<html>
...
<div id="content">
...
<div class="listing">
...
<div></div>
<div></div>
<div class='foo'>
<h3>Get me 1</h3>
<a>and me too 1</a>
</div>
</div>
<div class="listing">
...
<div></div>
<div></div>
<div class='foo'>
<h3>Get me 2</h3>
<a>and me too 1</a>
</div>
</div>
....
</div>
</html>
This is my code. I am trying to get a list of array that has the values of the h3 and a tags in each array. To do that, I needed to get each listing, and then get the h3 and a tag's value in each listing.
这是我的代码。我正在尝试获取一个数组列表,其中包含 h3 的值和每个数组中的一个标签。为此,我需要获取每个列表,然后获取每个列表中的 h3 和标签值。
$html_dom = new DOMDocument();
@$html_dom->loadHTML($html);
$x_path = new DOMXPath($html_dom);
$nodes= $x_path->query("//div[@id='content']//div[@class='listing']");
foreach ($nodes as $node)
{
// I want to further dig down here using query on a DOMNode
}
回答by Gordon
Pass the node as the second argument to DOMXPath::query
将节点作为第二个参数传递给 DOMXPath::query
contextnode: The optional contextnode can be specified for doing relative XPath queries. By default, the queries are relative to the root element.
contextnode:可以指定可选的 contextnode 来进行相关的 XPath 查询。默认情况下,查询是相对于根元素的。
Example:
例子:
foreach ($nodes as $node) {
foreach ($x_path->query('h3|a', $node) as $child) {
echo $child->nodeValue, PHP_EOL;
}
}
This uses the UNION operatorfor a result of
这将UNION 运算符用于结果
Get me 1
and me too 1
Get me 2
and me too 1
If you don't need any complex querying, you can also do
如果你不需要任何复杂的查询,你也可以这样做
foreach ($nodes as $node) {
foreach ($node->getElementsByTagName('a') as $a) {
echo $a->nodeValue, PHP_EOL;
}
}
Or even by iterating the child nodes (note that this includes all the text nodes)
甚至通过迭代子节点(请注意,这包括所有文本节点)
foreach ($nodes as $node) {
foreach ($node->childNodes as $child) {
echo $child->nodeName, PHP_EOL;
}
}
However, all of that is unneeded since you can fetch these nodes directly:
但是,所有这些都是不需要的,因为您可以直接获取这些节点:
$nodes= $x_path->query("/html/body//div[@class='listing']/div[last()]");
foreach ($nodes as $i => $node) {
echo $i, $node->nodeValue, PHP_EOL;
}
will give you two nodes in the last div child of all the divs with a class attribute value of listing and output the combined text node values, including whitespace
将在所有 div 的最后一个 div 子节点中为您提供两个节点,其类属性值为列表并输出组合的文本节点值,包括空格
0
Get me 1
and me too 1
1
Get me 2
and me too 1
Likewise, the following
同样,以下
"//div[@class='listing']/div[last()]/node()[name() = 'h3' or name() = 'a']"
will give you the four child H3 and A nodes and output
会给你四个孩子 H3 和 A 节点和输出
0Get me 1
1and me too 1
2Get me 2
3and me too 1
If you need to differentiate these by name while iterating over them, you can do
如果您需要在迭代它们时按名称区分它们,您可以这样做
foreach ($nodes as $i => $node) {
echo $i, $node->nodeName, $node->nodeValue, PHP_EOL;
}
which will then give
然后会给
0h3Get me 1
1aand me too 1
2h3Get me 2
3aand me too 1
回答by EPB
Provide your $node
as a context node.
提供您$node
作为上下文节点。
foreach ($nodes as $node)
{
$morenodes = $x_path->query(".//h3", $node);
}
See $contextnode
in the manual: http://php.net/manual/en/domxpath.query.php
参见$contextnode
手册:http: //php.net/manual/en/domxpath.query.php
回答by Fei
Just to make it complete, there is a DOMNode::getNodePath
method which returns xpath of that node. So you can also use $x_path->query($node->getNodePath().'//h3')
为了使它完整,有一个DOMNode::getNodePath
方法可以返回该节点的 xpath。所以你也可以使用$x_path->query($node->getNodePath().'//h3')