关于xml:PHP SimpleXML xpath查询结果

PHP SimpleXML xpath query results

我一直在寻找这个,我找到的答案似乎说明了我认为我理解的东西。很明显我错过了什么。我对XPath查询的结果感到困惑。我简化了我的问题,以便在这里发布一个测试用例。

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

示例XML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<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>

这是测试代码。

1
2
3
4
5
6
7
8
$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'));

代码输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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文档中的所有元素,而不考虑从中调用该xpath的上下文节点。要使xpath注意上下文节点,需要在xpath的开头添加一个点(.)。在xpath中,(.引用当前上下文节点:

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