我目前有以下XML结构:
<root>
<maininfo>
<node>
<tournament_id>3100423</tournament_id>
<games>
<a_0>
<id>23523636</id>
<type>
<choice_4>
<choice_id>345</choice_id>
<choice_4>
<choice_9>
<choice_id>345</choice_id>
<choice_9>
... etc
</type>
</a_0>
<a_1></a_1>
<a_2></a_2>
...etc
</games>
</info>
</node>
</root>
我可以很容易地获得第一个节点元素"a_0"的id,只需执行以下操作:
maininfo[0]->a_3130432[0]->games[0]->a_1[0]->id;
我的问题是:如何自动迭代(使用foreach)所有a_0
、a_1
、a_2
,并获得这些节点元素中的每个元素及其所有子元素的值,如<choice_id>345</choice_id>
中的"345"?
a_0
、a_1
+choice_4
、choice_9
的子元素的结束数字是动态创建的,并且在_[数字]中没有逻辑为每个下一个元素加+1。
正如前面在Stackoverflow(例如在Read XML dynamic PHP中)和PHP手册(例如在Basic SimpleXML用法)中所概述的那样,您可以使用foreach
迭代所有子元素。
例如,检查所有a_*
元素,它只是
foreach ($xml->maininfo->node->games[0] as $name => $a) {
echo $name, "'n";
}
输出:
a_0
a_1
a_2
然后,您需要再次对这些->type
子级进行迭代。在纯PHP中,通过将一个foreach
放入另一个:,可以实现
foreach ($xml->maininfo->node->games[0] as $name => $a) {
echo $name, "'n";
if (!$a->type[0]) {
continue;
}
foreach ($a->type[0] as $name => $choice) {
echo ' +- ', $name, "'n";
}
}
现在输出:
a_0
+- choice_4
+- choice_9
a_1
a_2
这开始变得有点复杂。正如您所能想象的,由于XML以其树结构而闻名,您并不是第一个遇到这个问题的人。因此,人们发明了一种从XML文档中获取元素的查询语言:Xpath。
使用Xpath,您可以像访问文件系统一样访问XML数据。正如我所知道的,每个a_*
元素都是games
的子元素,而每个choice_*
元素都是类型的子元素
/*/maininfo/node/games/*/type/*
^ ^ ^
| | choice_*
root |
a_*
在PHP Simplexml中,这看起来像:
$choices = $xml->xpath('/*/maininfo/node/games/*/type/*');
foreach ($choices as $choice) {
echo $choice->getName(), ': ', $choice->choice_id, "'n";
}
输出:
choice_4: 345
choice_9: 345
如本例所示,现在使用单个foreach
检索数据。
如果您也需要访问<a_*>
元素,则需要拥有多个foreach
的或自己的迭代,但这甚至是一个更高级的主题,我认为这将超出您的问题的范围。
我希望到目前为止这是有帮助的。同样参见SimpleXMLElement::children()
,它也提供了所有子项(如第一个示例中的->games[0]
)。所有示例代码都可以作为一个有效的交互式在线演示使用。
如果我理解得很好,你可以做一些事情,比如:
for($i = 0; $i < $max; ++$i){
$a = $parentNode->{'a_'.$i};
}
使用SimpleXML:可以非常容易地完成此操作
<?php
$xmlStr = "<?xml version='1.0' standalone='yes'?>
<root>
<maininfo>
<node>
<tournament_id>3100423</tournament_id>
<games>
<a_0>
<id>23523636</id>
<type>
<choice_4>
<choice_id>345</choice_id>
</choice_4>
<choice_9>
<choice_id>345</choice_id>
</choice_9>
</type>
</a_0>
<a_1></a_1>
<a_2></a_2>
</games>
</node>
</maininfo>
</root>";
$xmlRoot = new SimpleXMLElement($xmlStr);
$i = 0;
foreach($xmlRoot->maininfo[0]->node[0]->games[0] as $a_x)
{
echo $i++ . " - " . htmlentities($a_x->asXML()) . "<br/>";
}
?>
我修改了XML字符串的某些部分,使其语法正确。您可以在查看结果http://phpfiddle.org/main/code/56q-san