使用 PHP SimpleXML 选择具有特定名称的所有节点 - 附上源代码

Ale*_*ber 3 php xpath simplexml

在下面的 XML 文件中,我试图打印所有TestItem节点,但只获取 4 个outer节点。

有谁知道,如何打印每个具有该名称的节点,而不管它们的位置如何?

数据.xml:

<?xml version="1.0"?>
<Tests>
    <TestItem Name="UpdateBootProfile" Result="PASS" />
    <TestItem Name="NRB Boot" Result="PASS">
      <TestItem Name="Boot Test" Result="PASS">
        <TestItem Name="PreparePowerSupply" Result="PASS" />
        <TestItem Name="ApplyBatteryVoltage" Result="PASS" />
        <TestItem Name="Shelf Mode test" Result="PASS">
        </TestItem>
        <TestItem Name="ApplyUSBVoltage" Result="PASS" />
        <TestItem Name="DetectBoard" Result="PASS" />
        <TestItem Name="Device Current Profile" Result="PASS" />
        <TestItem Name="Device Connection" Result="PASS">
        </TestItem>
      </TestItem>
    </TestItem>
    <TestItem Name="Check device Type" Result="PASS" />
    <TestItem Name="Assign BSN and Erase EFS" Result="PASS">
    </TestItem>
</Tests>
Run Code Online (Sandbox Code Playgroud)

解析.php:

<?php
        $tmp = 'data.xml';
        $str = file_get_contents($tmp);
        $xml = new SimpleXMLElement($str);
        $items = $xml->xpath('TestItem');

        while(list( , $test) = each($items)) {
                printf("%s %s\n", $test['Name'], $test['Result']);
        }
?>
Run Code Online (Sandbox Code Playgroud)

php -f parse.php输出(为什么只列出 4 个测试项?):

UpdateBootProfile PASS
NRB Boot PASS
Check device Type PASS
Assign BSN and Erase EFS PASS
Run Code Online (Sandbox Code Playgroud)

在 CentOS 6.3 命令行上使用 PHP 5.3.5。

更新:

建议//TestItem适用于我上面的简单测试用例,谢谢。

但是对于我的真实数据它仍然失败(我无法在此处粘贴):

# grep -w TestItem my_real_file_May_2013_09_35_38.xml |wc -l
143

# php -f parse.php |wc -l
86
Run Code Online (Sandbox Code Playgroud)

有没有人有想法,这会//TestItem错过一些节点?

更新 2:

实际上它有效!由于一些</TestItem>结束标记,上面的 grep 突击队计算了更多行:-)

Nul*_*ter 5

你可以简单地做到这一点

$testitems = simplexml_load_file("testitem.xml");
if(count($testitems)):
    $result = $testitems->xpath("//TestItem");

    //echo "<pre>";print_r($result);die;
    foreach ($result as $item):
        echo "Name ".$item['Name'] ." and result ". $item['Result'];
        echo "<hr>";
    endforeach;
endif;
Run Code Online (Sandbox Code Playgroud)

通过以上操作,您将获得所有具有元素的<TestItem>元素。