为什么在子元素上调用SimpleXMLElement::xpath方法时会得到父元素



为什么在子元素上调用SimpleXMLElement::xpath()方法时会得到父元素?

示例:

$xml = '<root>
<node>
<tag v="foo"/>
<tag v="bar"/>
</node>
<node>
<tag v="foo"/>
</node>
<node>
<tag v="foo"/>
<tag v="bar"/>
</node>
</root>';
$simpleXML = new SimpleXMLElement($xml);
$nodeList = $simpleXML->xpath('//node');
foreach ($nodeList as $node) {
$node->xpath('//tag');
}

这里,$node->xpath('//tag')在每次迭代时返回文档的所有<tag>xml标记,而不是仅返回<node>标记的子<tag>元素。

//tag.//tag//descendent::tag之间的差异:

  • //tag检索文档中任何位置的所有tag元素。

  • CCD_ 11检索上下文节点处或其下的所有CCD_。

  • CCD_ 13检索上下文节点下的所有CCD_。

另请参见

  • 两者之间有什么区别。//和//*在XPath中

在XPath中,当使用//时,表示的是相对于当前节点的任何位置上的节点。使用XPath,它还包括文档中更高级别的节点以及包含在该元素中的节点。

在这种特殊情况下,有几种方法可以解决。。。

参考What';在xpath中//node和/descendant::node之间的区别是什么?,您可以使用子轴。。。

foreach ($nodeList as $node) {
$node->xpath('descendant::tag');
}

其仅使用基本节点内部的节点(在这种情况下为$node(。

或者,如果文档中的层次结构与文档中的完全相同,则更简单的方法是使用SimpleXML对象表示法(每个对象都有一个循环显示(。。。

foreach ($nodeList as $node) {
// For each enclosed tag
foreach ( $node->tag as $tag )  {
// Echo the v attribute
echo $tag['v'].PHP_EOL;
}
}