为什么在子元素上调用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;
}
}