Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何使用动态子节点遍历XML元素节点_Php_Xml_Foreach_Simplexml - Fatal编程技术网

Php 如何使用动态子节点遍历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>

我目前拥有以下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>
我的问题是: 如何(使用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更好,所以这是一个现成的好工具。