有没有办法在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>
这是我的代码。我试图获得一个数组列表,其中包含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
}
答案 0 :(得分:31)
将节点作为第二个参数传递给DOMXPath::query
contextnode :可以指定可选的contextnode来执行相对XPath查询。默认情况下,查询是相对于根元素的。
示例:
foreach ($nodes as $node) {
foreach ($x_path->query('h3|a', $node) as $child) {
echo $child->nodeValue, PHP_EOL;
}
}
这使用UNION operator作为
的结果Get me 1
and me too 1
Get me 2
and me too 1
如果您不需要任何复杂的查询,也可以
foreach ($nodes as $node) {
foreach ($node->getElementsByTagName('a') as $a) {
echo $a->nodeValue, PHP_EOL;
}
}
甚至通过迭代子节点(请注意,这包括所有文本节点)
foreach ($nodes as $node) {
foreach ($node->childNodes as $child) {
echo $child->nodeName, PHP_EOL;
}
}
但是,所有这些都是不必要的,因为您可以直接获取这些节点:
$nodes= $x_path->query("/html/body//div[@class='listing']/div[last()]");
foreach ($nodes as $i => $node) {
echo $i, $node->nodeValue, PHP_EOL;
}
将在所有div的最后一个div子节点中为您提供两个节点,其类属性值为listing,并输出组合的文本节点值,包括空格
0
Get me 1
and me too 1
1
Get me 2
and me too 1
同样,以下
"//div[@class='listing']/div[last()]/node()[name() = 'h3' or name() = 'a']"
将为您提供四个子H3和A节点以及输出
0Get me 1
1and me too 1
2Get me 2
3and me too 1
如果您需要在迭代它们时按名称区分这些,可以执行
foreach ($nodes as $i => $node) {
echo $i, $node->nodeName, $node->nodeValue, PHP_EOL;
}
然后会给出
0h3Get me 1
1aand me too 1
2h3Get me 2
3aand me too 1
答案 1 :(得分:10)
将您的$node
作为上下文节点提供。
foreach ($nodes as $node)
{
$morenodes = $x_path->query(".//h3", $node);
}
请参阅手册中的$contextnode
:http://php.net/manual/en/domxpath.query.php
答案 2 :(得分:2)
只是为了完成它,有一个DOMNode::getNodePath
方法返回该节点的xpath。所以你也可以使用$x_path->query($node->getNodePath().'//h3')