3

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

有人知道,如何打印具有该名称的每个节点,无论它们的位置如何?

数据.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>

解析.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']);
        }
?>

php -f parse.php输出(为什么它只列出 4 个 TestItem?):

UpdateBootProfile PASS
NRB Boot PASS
Check device Type PASS
Assign BSN and Erase EFS PASS

在 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

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

更新 2:

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

4

3 回答 3

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;

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

于 2013-05-08T12:00:33.267 回答
2

使用以下 xpath 选择节点,无论它们在树中的位置如何:

$items = $xml->xpath('//TestItem');

或者

$items = $xml->xpath('//TestItem/TestItem');

如果您只需要叶子节点。

输出(来自第二个):

UpdateBootProfile PASS
NRB Boot PASS
Boot Test PASS
PreparePowerSupply PASS
ApplyBatteryVoltage PASS
Shelf Mode test PASS
ApplyUSBVoltage PASS
DetectBoard PASS
Device Current Profile PASS
Device Connection PASS
Check device Type PASS
Assign BSN and Erase EFS PASS

注意//. 在W3schools XPath 教程中了解更多信息。

于 2013-05-08T11:52:02.250 回答
-1
function printxml($xml,$deep = 4){
if($xml instanceOf SimpleXMLElement)
    $xml = (array)$xml;
    foreach($xml->TestItem as $t){
        if(is_array($t) && $deep > 0)
            printxml($t, $deep-1);
        else
            echo $t['Name'].' '.$t['Result'];
    }
}

试试看,只需要做计数器来获得 xml 的深度,在你的情况下是 4 个级别。

于 2013-05-08T11:53:50.820 回答