PHP/XPath:使用SimpleXML迭代XML中的祖先节点
我需要遍历PHP/XPath:使用SimpleXML迭代XML中的祖先节点,php,xml,xpath,Php,Xml,Xpath,我需要遍历祖先节点,以获得相应的BrowseNodeId和Name值。如何使用XPath实现这一点?我正在尝试以下方法,但不起作用: //BrowseNode[1]//Ancestors[1]/BrowseNode/BrowseNodeId/text() //BrowseNode[1]//Ancestors[1]/BrowseNode/Name/text() 我认为XPath的//部分实际上是在搜索整个XML树。我需要做的是访问每个节点以获得所需的值。我该怎么做?在下面的例子中,我想要:欧洲-
祖先
节点,以获得相应的BrowseNodeId
和Name
值。如何使用XPath实现这一点?我正在尝试以下方法,但不起作用:
//BrowseNode[1]//Ancestors[1]/BrowseNode/BrowseNodeId/text()
//BrowseNode[1]//Ancestors[1]/BrowseNode/Name/text()
我认为XPath的//
部分实际上是在搜索整个XML树。我需要做的是访问每个节点以获得所需的值。我该怎么做?在下面的例子中,我想要:欧洲->历史->科目->书籍
XML示例:
<BrowseNode>
<BrowseNodeId>4952</BrowseNodeId>
<Name>France</Name>
<Ancestors>
<BrowseNode>
<BrowseNodeId>4935</BrowseNodeId>
<Name>Europe</Name>
<Ancestors>
<BrowseNode>
<BrowseNodeId>9</BrowseNodeId>
<Name>History</Name>
<Ancestors>
<BrowseNode>
<BrowseNodeId>1000</BrowseNodeId>
<Name>Subjects</Name>
<IsCategoryRoot>1</IsCategoryRoot>
<Ancestors>
<BrowseNode>
<BrowseNodeId>283155</BrowseNodeId>
<Name>Books</Name>
</BrowseNode>
</Ancestors>
</BrowseNode>
</Ancestors>
</BrowseNode>
</Ancestors>
</BrowseNode>
</Ancestors>
</BrowseNode>
4952
法国
4935
欧洲
9
历史
1000
学科
1.
283155
书
可能尝试定位最终节点,然后提取祖先
<?php
$xml = "
<BrowseNode>
<BrowseNodeId>4952</BrowseNodeId>
<Name>France</Name>
<Ancestors>
<BrowseNode>
<BrowseNodeId>4935</BrowseNodeId>
<Name>Europe</Name>
<Ancestors>
<BrowseNode>
<BrowseNodeId>9</BrowseNodeId>
<Name>History</Name>
<Ancestors>
<BrowseNode>
<BrowseNodeId>1000</BrowseNodeId>
<Name>Subjects</Name>
<IsCategoryRoot>1</IsCategoryRoot>
<Ancestors>
<BrowseNode>
<BrowseNodeId>283155</BrowseNodeId>
<Name>Books</Name>
</BrowseNode>
</Ancestors>
</BrowseNode>
</Ancestors>
</BrowseNode>
</Ancestors>
</BrowseNode>
</Ancestors>
</BrowseNode>
";
$sxe = simplexml_load_string($xml);
// Set the target to reach
$target = current($sxe->xpath("//BrowseNode[./BrowseNodeId = '283155']"));
// Get all names from root to target
$names = array_map('strval', $target->xpath('ancestor-or-self::Ancestors/BrowseNode/Name'));
print_r($names);
// Array
// (
// [0] => Europe
// [1] => History
// [2] => Subjects
// [3] => Books
// )
// Get all ids from root to target
$ids = array_map('strval', $target->xpath('ancestor-or-self::Ancestors/BrowseNode/BrowseNodeId'));
print_r($ids);
// Array
// (
// [0] => 4935
// [1] => 9
// [2] => 1000
// [3] => 283155
// )
// Final
$combined = array_combine($ids, $names);
print_r($combined);
// Array
// (
// [4935] => Europe
// [9] => History
// [1000] => Subjects
// [283155] => Books
// )
xpath(“//BrowseNode[./BrowseNodeId='283155']”);
//获取从根到目标的所有名称
$names=array_-map('strval',$target->xpath('祖先或自我::祖先/BrowseNode/Name');
打印(姓名);
//排列
// (
//[0]=>欧洲
//[1]=>历史记录
//[2]=>主题
//[3]=>书籍
// )
//获取从根到目标的所有ID
$ids=array_-map('strval',$target->xpath('祖先或自我::祖先/BrowseNode/BrowseNodeId');
打印(ID);
//排列
// (
// [0] => 4935
// [1] => 9
// [2] => 1000
// [3] => 283155
// )
//决赛
$combined=array\u combined($ids,$names);
印刷费(合计);
//排列
// (
//[4935]=>欧洲
//[9]=>历史
//[1000]=>主题
//[283155]=>书籍
// )
在下面的例子中,我想要:欧洲
->历史->科目->书籍
我认为你需要:
//Ancestors/BrowseNode/Name
或者只需迭代//祖先/BrowseNode
结果,并使用任何DOM方法获取名称
和BrowseNodeId
子级
/BrowseNode/Ancestors//BrowseNode/Name/text()
将与您的样品
但是,它将搜索所有定义为“第一个”祖先元素的节点。从最深的BrowseNode
处反转和查看也可以做到同样的效果
在XSLT中,可行且必要的替代方法是使用键来提高效率。我可能误解了您对所需内容的准确描述,但希望不会。此代码段查找所有“顶级”的BrowseNode
元素并在其上循环,每次都会获取它们关联的祖先BrowseNode
元素
// Get top level BrowseNode elements
$browse_nodes = $xml->xpath('//BrowseNodes/BrowseNode');
foreach ($browse_nodes as $browse_node) {
// Get ancestor BrowseNode elements
$ancestors = $browse_node->xpath('Ancestors//BrowseNode');
// Do whatever you like with them! :-)
}
我认为这行不通。我拥有的XML非常庞大,有很多顶级BrowseNode
元素。另外,我只对每个顶级BrowseNode
元素的祖先/BrowseNode
感兴趣。意思是,我需要这样的东西://BrowseNode[1]/祖先/BrowseNode
,然后//BrowseNode[2]/祖先/BrowseNode
,然后//BrowseNode[3]/祖先/BrowseNode
。。。问题是//正在搜索整个树,我想。我需要的是遍历每个顶级BrowseNode
oic的子树,可能尝试单斜杠xpath('/祖先/BrowseNode'),然后是xpath('/祖先/BrowseNode/祖先/BrowseNode'),等等。对此可能不需要xpath。您可以像遍历数组一样遍历一组子对象。@Alejandro的答案比您接受的答案要好。事实上,接受的答案是错误的,因为它根本没有获得任何节点:XPath表达式/祖先/BrowseNode
没有选择任何节点,因为XML文档没有名为祖先的顶级元素。请考虑接受一个正确的答案,因为接受错误的答案可能误导他人。
// Get top level BrowseNode elements
$browse_nodes = $xml->xpath('//BrowseNodes/BrowseNode');
foreach ($browse_nodes as $browse_node) {
// Get ancestor BrowseNode elements
$ancestors = $browse_node->xpath('Ancestors//BrowseNode');
// Do whatever you like with them! :-)
}