您好我正在尝试使用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的新手。
答案 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);
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)
);
}