解析嵌套XML节点的属性值
我试图用PHP解析XML,但是我遇到了问题。解析嵌套XML节点的属性值
所以XML看起来像这样(简体)
<weatherdata>
<forecast>
<tabular>
<time from="2015-09-25T20:00:00" to="2015-09-25T23:00:00" period="3">
<symbol number="4" numberEx="4" name="Cloudy" var="04" />
</time>
<time from="2015-09-25T23:00:00" to="2015-09-26T05:00:00" period="0">
<symbol number="9" numberEx="46" name="Light rain" var="46" />
</time>
.....
我能够从值加载所有的时间>是这样的:
foreach($xml->forecast->tabular as $forecastItem){
$attr = $forecastItem->attributes();
$froms[] = $attr['from'];
}
但后来我试图加载这样的符号的名称属性:
foreach($xml->forecast->tabular as $forecastItem){
$attr = $forecastItem->attributes();
$froms[] = $attr['from'];
$attr2 = $forecastItem->symbol->attributes();
$names[] = $attr2['name'];
}
它显示我main()节点不存在的错误。基本上我想要做的就是将所有名称加载到一个数组中,就像来自froms一样。
您应该使用$xml->forecast->tabular->children()
遍历XML的孩子:
<?php
$data = '<weatherdata>
<forecast>
<tabular>
<time from="2015-09-25T20:00:00" to="2015-09-25T23:00:00" period="3">
<symbol number="4" numberEx="4" name="Cloudy" var="04" />
</time>
<time from="2015-09-25T23:00:00" to="2015-09-26T05:00:00" period="0">
<symbol number="9" numberEx="46" name="Light rain" var="46" />
</time>
</tabular>
</forecast>
</weatherdata>';
$xml = simplexml_load_string($data);
$froms = array();
$names = array();
foreach($xml->forecast->tabular->children() as $forecastItem){
$attr = $forecastItem->attributes();
$froms[] = $attr['from'];
$attr2 = $forecastItem->symbol->attributes();
$names[] = $attr2['name'];
}
print_r($froms);
print_r($names);
Array
(
[0] => SimpleXMLElement Object
(
[0] => 2015-09-25T20:00:00
)
[1] => SimpleXMLElement Object
(
[0] => 2015-09-25T23:00:00
)
)
Array
(
[0] => SimpleXMLElement Object
(
[0] => Cloudy
)
[1] => SimpleXMLElement Object
(
[0] => Light rain
)
)
你得到完整的错误信息是:
警告:主要( ):节点不再存在于...
接着下面的代码的行数:
$attr2 = $forecastItem->symbol->attributes();
它可能不是很清楚,你有什么错误实际上是约。为了更好地理解它,您必须了解一下您在此使用的SimpleXmlElement的内部工作。
如果你被它的名称访问一个子元素,为examle喜欢这里的<symbol>
元素:
$forecastItem->symbol
SimpleXML扩展将创建节点上即时为暂时的,没有这样的时候子元素已经存在。这样做是为了在飞行中添加它。例如:
$forecastItem->symbol = 'hello world!';
echo $forecastItem->asXML();
将显示:
<tabular>
<time from="2015-09-25T20:00:00" to="2015-09-25T23:00:00" period="3">
<symbol number="4" numberEx="4" name="Cloudy" var="04"/>
</time>
<time from="2015-09-25T23:00:00" to="2015-09-26T05:00:00" period="0">
<symbol number="9" numberEx="46" name="Light rain" var="46"/>
</time>
<symbol>hello world!</symbol></tabular>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
而这也解释了为什么您的代码不起作用。由于符号元素只是暂时性的,而你没有设置它,SimpleXML只是试图告诉你,这个节点不再存在。这是正确的,当你试图读取一个不存在的节点的属性:
$forecastItem->symbol->attributes(); // no write, but a read operation
因此,然后工作,预期如果节点存在如这个现有的符号元素:
$forecastItem->time->symbol->attributes();
这很可能是您在编写代码时位于文档树中不同位置的标志。
非常感谢您的澄清 – Jachym
@Alan谢谢,我刚刚也注意到了,好像我们在同一时间编辑它。 –
没问题,重要的是,它的现予以更正。 :) –