Php 如何使用动态子节点遍历XML元素节点
我目前拥有以下XML结构:Php 如何使用动态子节点遍历XML元素节点,php,xml,foreach,simplexml,Php,Xml,Foreach,Simplexml,我目前拥有以下XML结构: <root> <maininfo> <node> <tournament_id>3100423</tournament_id> <games> <a_0> <id>23523636</id> <type> <choice_4>
<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>
我的问题是:
如何(使用foreach)自动迭代所有a_0
、a_1
、a_2
,并获得这些节点元素及其所有子元素(如345
中的“345”)的值
a\u 0
,a\u 1
+选择项4,choice\u 9
的子项的结束数是动态创建的,{[number]中没有逻辑,每个下一个元素加上+1。如果我理解得很好,您可以执行以下操作:
for($i = 0; $i < $max; ++$i){
$a = $parentNode->{'a_'.$i};
}
($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/>";
}
?>
正如前面在Stackoverflow(例如中)以及PHP手册(例如中)中概述的那样,您可以使用foreach
迭代所有子元素
例如,要查看所有a.*
元素,它只是
foreach ($xml->maininfo->node->games[0] as $name => $a) {
echo $name, "\n";
}
输出:
a_0
a_1
a_2
choice_4: 345
choice_9: 345
然后,您希望再次迭代这些子对象的->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";
}
输出:
a_0
a_1
a_2
choice_4: 345
choice_9: 345
如本例所示,现在使用单个foreach
检索数据
如果您还需要访问,它也为所有儿童提供了权限(如第一个示例中的->games[0]
)。所有示例代码都可以使用。似乎只需打印所有示例代码(包括节点名称)?也许我只是看错了小提琴。我想做的是能够通过单个$value_varsI访问/迭代不同元素的值。我不确定XPath是否通常是“像访问文件系统一样访问XML数据”,尽管我想这样一个相对简单的表达式很容易让人想起文件glob。我可能会在某个地方找到它,但是XPath可以计算部分通配符,比如//a_*
?@IMSoP:文件系统比较是一个类比,它并不完全相同。部分通配符不能像您所描述的那样工作,它与字符串表达式一起工作,或者-在PHP中可能-将正则表达式匹配函数放在其中。好的,谢谢。总有一天我会花时间学习XPath的基础知识:)XPath 1.0有时有点过时,但通常比X foreaches更好,所以这是一个现成的好工具。