php将复杂的xml元素解析为顺序

时间:2014-09-29 14:13:29

标签: php xml parsing


我正在尝试编写一个PHP脚本,它查看现有的XML日志,然后将此信息打印到屏幕上。 我一直在看simplexml_load_file()和其他方法,但我被困在一位。 我想按照它们在xml文件中出现的顺序显示元素中的所有信息。 我知道如何提取值和属性,但我不知道如何循环测试和检测  并按下图所示的顺序打印它们(即45,46,47,48,49,50。 我无法改变xml结构,因为它超出了我的控制范围。

这样做的最佳方法是什么?

由于

  <xml>
      <test name="test1">
        <time date="29/09/2014" />
        <message line="45" type="LOG">
          <description>Example 1</description>
        </message>
        <message line="46" type="TEST">
          <description>Example 2</description>
        </message>
        <verification line="47">
          <result type="pass" file="abc.py">
              <description>button was available</description>
              <description type="DETAILED"></description>
          </result>
        </verification>
        <message line="48" type="LOG">
          <description>Example 3</description>
        </message>
        <verification line="49">
          <result type="pass" file="abc.py">
              <description>button available</description>
              <description type="DETAILED"></description>
          </result>
        </verification>
        <message line="50" type="LOG">
          <description>Example 4</description>
        </message>
      </test>
  </xml>

示例输出:

Test: test1
Date: 29/09/2014
Message - 45 - Log - Description: Example 1
Message - 46 - TEST - Description: Example 2
Verification - 47 - result=pass - button was available - DETAILED - file=abc.py
Message - 48 - Log - Description: Example 3
Verification - 49 - result=pass - button available - DETAILED - file=abc.py
Message - 50 - Log - Description: Example 4

3 个答案:

答案 0 :(得分:0)

您可以尝试将xml文件转换为数组,然后获取数据:数组中的键和值:

<?php
$xml='<xml>
      <test name="test1">
        <time date="29/09/2014" />
        <message line="45" type="LOG">
          <description>Example 1</description>
        </message>
        <message line="46" type="TEST">
          <description>Example 2</description>
        </message>
        <verification line="47">
          <result type="pass" file="abc.py">
              <description>button was available</description>
              <description type="DETAILED"></description>
          </result>
        </verification>
        <message line="48" type="LOG">
          <description>Example 3</description>
        </message>
        <verification line="49">
          <result type="pass" file="abc.py">
              <description>button available</description>
              <description type="DETAILED"></description>
          </result>
        </verification>
        <message line="50" type="LOG">
          <description>Example 4</description>
        </message>
      </test>
  </xml>';
function xml_to_array($input, $callback = null, $recurse = false) {
                    $data = ((!$recurse) && is_string($input))? simplexml_load_string($input, 'SimpleXMLElement', LIBXML_NOCDATA): $input;
                    if ($data instanceof SimpleXMLElement) $data = (array) $data;
                    if (is_array($data)) foreach ($data as &$item) $item = xml_to_array($item, $callback, true);
                    return (!is_array($data) && is_callable($callback))? call_user_func($callback, $data): $data;
            } 


$xml=xml_to_array($xml);//transform you xml file to an array

function get_array_values($xml){ //search for all values in the required array
 foreach($xml as $key => $value) { 
    if(is_array($value)){
      get_array_values($value);
    }else{print $key." : ".$value."\n";}
 }
}
get_array_values($xml);
?>

输出:

name : test1
date : 29/09/2014
line : 45
type : LOG
description : Example 1
line : 46
type : TEST
description : Example 2
line : 48
type : LOG
description : Example 3
line : 50
type : LOG
description : Example 4
line : 47
type : pass
file : abc.py
0 : button was available
type : DETAILED
line : 49
type : pass
file : abc.py
0 : button available
type : DETAILED

答案 1 :(得分:0)

如果您想保留订单,可以尝试与Message和Verification匹配的xpath表达式。

试试这个$nodes = $xmlObj->xpath('test/*');

然后你可以像这样迭代结果:

foreach ($nodes as $nodeType => $node) {
    //you can get node name with $node->getName()
    //node attributes with $node->attributes
    //and iterate node children with foreach($node->children() as $childNode)
}

答案 2 :(得分:0)

感谢montexristos,我现在得到了答案。以下是我需要的完整代码。

 <?php
 $xmlObj= simplexml_load_file('data.xml');
 $nodes = $xmlObj->xpath('test/*');
 print "Test: ".$xmlObj->test['name']."<br>";

 foreach ($nodes as $nodeType => $node) {
     $name = $node->getName();
     if ($name == "time"){
         print "Date: ".$node['date']."<br>";
     }else if ($name == "message"){
         print "Message - ".$node['line']." - ".$node['type']." - Description: ".$node->description."<br>";
     }else if ($name == "verification"){
         print "Verification - ".$node['line']." - result=".$node->result['type']." - ".$node->result->description." - ".$node->result->description[1]['type']." - ".$node->result['file']."<br>";
     }
 }
 ?>