Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP/XPath:使用SimpleXML迭代XML中的祖先节点_Php_Xml_Xpath - Fatal编程技术网

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! :-)
}