在SimpleXML对象上使用xPath的Foreach循环返回重复数据

时间:2012-03-11 04:54:18

标签: php xml simplexml

任何人都可以帮我解释为什么以下内容会返回重复数据吗?

<?php
$xml_test = '<array key="results">
    <array key="123">
        <string key="mask">1234</string>
    </array>
    <array key="987">
        <string key="mask">5678</string>
    </array>
</array>';

$load_test = simplexml_load_string($xml_test);

foreach ($load_test as $array)
{
    $mask = $array->xpath('//string[@key="mask"]');

    print 'Mask: ' . $mask[0] . '<br />';
}

返回:

Mask: 1234
Mask: 1234

如果我在foreach循环中抛出print_r($ array),我得到:

SimpleXMLElement Object
(
    [@attributes] => Array
        (
            [key] => 123
        )

    [string] => 1234
)
Mask: 1234

SimpleXMLElement Object
(
    [@attributes] => Array
        (
            [key] => 987
        )

    [string] => 5678
)
Mask: 1234

到底是怎么回事?当我使用xPath表达式时,为什么我在获取重复的掩码时,$ array都没有显示重复数据。

3 个答案:

答案 0 :(得分:3)

您正在为XML中的每个<array>节点执行两次相同的xpath查询。不需要外环。只需执行xpath查询,然后遍历其结果。

$mask = $array->xpath('//string[@key="mask"]');
print 'Mask: ' . $mask[0] . '<br />';
print 'Mask: ' . $mask[1] . '<br />';

首先执行xpath查询,然后循环遍历它:

$mask = $array->xpath('//string[@key="mask"]');
foreach ($mask as $m) {
   echo $m;
}

答案 1 :(得分:1)

使用xpath()/中启动位置路径会使其成为“绝对”,而您希望查询$array元素的“相对”。对于您的示例,只需取出//

foreach ($load_test as $array)
{
    $mask = $array->xpath('string[@key="mask"]');

    print 'Mask: ' . $mask[0] . '<br />';
}

另见http://www.sitepoint.com/forums/showthread.php?723058-php-xml-loop&p=4778177&viewfull=1#post4778177

答案 2 :(得分:0)

直到我能更好地理解正在发生的事情,以下输出我所追求的内容;允许我匹配关键属性。

$xml_test = '<array key="results">
    <array key="123">
        <string key="mask">1234</string>
        <string key="name">mick</string>
    </array>
    <array key="987">
        <string key="mask">5678</string>
        <string key="name">bob</string>
    </array>
</array>';

$simplexml= new SimpleXMLElement($xml_test);

$test = $simplexml->xpath('//array/array');

$loop = 0;
foreach ($test as $result)
{
    $mask = $result->xpath('//string[@key="mask"]');
    $name = $result->xpath('//string[@key="name"]');

    echo "Mask: " . $mask[$loop] . '<br />';
    echo "Name: " . $name[$loop];
    $loop++;
}

返回:

Mask: 1234
Name: mick

Mask: 5678
Name: bob

不确定上面是多么干净,但它最终会做我需要做的事情。