PHP XMLREADER嵌套元素

时间:2014-07-09 07:29:06

标签: php xml xmlreader

您好我正在尝试使用XML Reader来读取一些我不知道元素名称的动态xml。我需要使用XML Reader而不是SimpleXML,因为我的服务器上可以使用它。 我遇到的麻烦是试图拥有可以处理嵌套和非嵌套元素的东西。 我的XML看起来像

<status>
  <state>active</state>
  <time>2014-07-15T04:00:00.000Z</time>
    <output-type>archive</output-type>
   <sources>
<source>
<class>audio</class>
<channels>
    <channel>
        <position>left</position>
        <average>0</average>
        <peak>0</peak>
    </channel>
    <channel>
        <position>right</position>
        <average>1095</average>
        <peak>1114</peak>
    </channel>
</channels>
</source>
</status>

但也可能看起来像:

<status>inactive</status>

我使用以下代码:

    while ($reader->read()) {
        if ($reader->nodeType == XMLReader::ELEMENT) {
            $element = $reader->name;
            //$elementarray[] = $element;
            echo $element;
            if ($reader->depth <1){echo"</br>";}
        }

        if ($reader->nodeType == XMLReader::TEXT) {
            $value = $reader->value;
            $valuearray[] = $value;
            echo " : ".$value."</br>";                 
        }
    }

此输出

1stElement2ndelement : text

在文档记录不足的XML Reader中我无法找到输出

1stElement:
2ndelement: text

我可以用。填充数组。

任何帮助都表示赞赏,因为我是PHP的新手。

1 个答案:

答案 0 :(得分:0)

不要发布伪xml。这不是有效的xml(元素名称不能以数字开头)。这使得理解/验证您的问题变得困难。 DOM可用吗?只有XMLReader而不是DOM会很奇怪。使用DOM,您可以使用Xpath,这样更容易使用。

因此,让我们假设一些选项xml。

$xml = <<<'XML'
<options>
  <one>1</one>
  <two>2</two>
</options>
XML;

XML阅读器将读取每个节点。记住最后一个元素节点的名称。如果找到文本节点而不是空,则将带有记住名称的内容添加到结果数组中。

$reader = new XMLReader();
$reader->open('data:/text/plain,'.urlencode($xml));

$result = [];
$element = null;
while ($reader->read()) {
  switch ($reader->nodeType) {
  case XMLReader::ELEMENT :
    $element = $reader->name;
    break;
  case XMLReader::TEXT :
    $value = $reader->value;
    if (trim($value) != '') {
      $result[$element] = $value;
    }
    break;
  }
}

var_dump($result);

输出:

array(2) {
  ["one"]=>
  string(1) "1"
  ["two"]=>
  string(1) "2"
}

在DOM中,可以只选择元素节点到列表中并迭代它们:

$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);

$result = [];
foreach ($xpath->evaluate('/options/*') as $node) {
  $result[$node->localName] = $node->nodeValue;
}

var_dump($result);

演示:https://eval.in/170803

DOMXpath :: evaluate()允许您使表达式相对于上下文节点并获取标量。因此,您通常会获取可以迭代的标量或节点列表。结果取决于Xpath表达式,因此您将始终知道。

$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);

foreach ($xpath->evaluate('//channels/channel') as $channel) {
  var_dump(
    $xpath->evaluate('string(position)', $channel),
    $xpath->evaluate('number(1095)', $channel),
    $xpath->evaluate('number(1114)', $channel)
  );
}

演示:https://eval.in/172551