PHP SimpleXML xpath 查询结果

PHP SimpleXML xpath query results

我搜索过这个,我找到的答案似乎是我认为我理解的。显然我错过了一些东西。我对 xPath 查询的结果感到困惑。我在此处将测试用例的问题简化为 post。

我的真实 xml 有几个不同深度的数据集节点。最终,我想获取具有给定标签的每个数据集元素,然后遍历它并获取字段值(在不同的位置(或深度),所以我认为我需要 xpath)。我可以使用 xpath 成功获取我想要的数据集元素。但是,当我在该结果对象上 运行 xpath 时,它会为我提供我想要的字段以及所有其他字段。我不明白为什么它不仅返回 field1、field2 和 field3。当我 print_r($value[0]) 时,它只显示我想要的字段。但是,当我 运行 $value[0] 上的 xpath 时,它 returns xml 文档中的所有字段。

样本XML

<myxml>
    <dataset label="wanteddata" label2="anotherlabel">
        <dataitem>
            <textdata>
                <field label="label1">field1</field>
                <field label="label2">field2</field>
                <field label="label3">field3</field>
            </textdata>
        </dataitem>
    </dataset>
    <dataset label="unwanteddata" label2="unwantedanotherlabel">
        <dataitem>
            <textdata>
                <field label="label4">field4</field>
                <field label="label5">field5</field>
                <field label="label6">field6</field>
            </textdata>
        </dataitem>
    </dataset>
</myxml>

这是测试代码。

$xmlstring = file_get_contents('simplexml_test.xml');
$xml = simplexml_load_string($xmlstring);
if ($xml === false) { 
    throw new Exception("Failed to load");
}

$value = $xml->xpath('//dataset[@label="wanteddata"]');
print_r($value[0]->xpath('//field'));

代码输出:

Array
(
[0] => SimpleXMLElement Object
    (
        [@attributes] => Array
            (
                [label] => label1
            )
    )
[1] => SimpleXMLElement Object
    (
        [@attributes] => Array
            (
                [label] => label2
            )
    )
[2] => SimpleXMLElement Object
    (
        [@attributes] => Array
            (
                [label] => label3
            )
    )
[3] => SimpleXMLElement Object
    (
        [@attributes] => Array
            (
                [label] => label4
            )
    )
[4] => SimpleXMLElement Object
    (
        [@attributes] => Array
            (
                [label] => label5
            )
    )
[5] => SimpleXMLElement Object
    (
        [@attributes] => Array
            (
                [label] => label6
            )
    )
)

//field 选择整个 XML 文档中的所有 <field> 元素,而不考虑调用该 XPath 的上下文节点。要使 XPath 关注上下文节点,您需要在 XPath 的开头添加一个点 (.)。在 XPath 中,(.) 引用当前上下文节点:

print_r($value[0]->xpath('.//field'));