【问题标题】:How to include every child element of a child element in output? PHP如何在输出中包含子元素的每个子元素? PHP
【发布时间】:2012-02-18 02:30:58
【问题描述】:

我有一个执行以下操作的小型应用程序:

  • 允许用户上传 XML 文件
  • 将 XML 文件解析为一个数组以使用 $_SESSION
  • 显示用户可以选择查看的父元素名称列表
  • 解析数组以显示所选父元素的子元素

问题是每个item都可以有孩子,可以有孩子,可以有孩子......等等......而且这种情况可以无限期地持续下去。

如何在最终输出中包含一个孩子的每个孩子?

XML 文件可能类似于:

<thing>
  <parents>
    <parent>
      <name>parent 1</name>
      <categories>
        <category>
          <name>category 1</name>
          <items>
            <item>
              <name>item 1 (gen 1)</name>
              <items>
                <item>
                  <name>sub-item 1 (gen 2)</name>
                  <items>
                    <item>
                      <name>sub-sub-item 1 (gen 3)</name>
                      ...this could continue forever..
                    </item>
                  </items>
                </item>
              </items>
            </item>
          </items>
        </category>
      </categories>
    </parent>
  </parents>
</thing>

我已经使用 PHP 的 SimpleXML 将 XML 解析为一个数组。每个文件都必须有一个父项、类别和第一代子项。以下代码解析了这 3 层结构,但除此之外我迷路了。

$output .= '<ul>';
foreach($xml['parents'] as $parent){
  $output .= '<li>'.$parent['name'].'</li>';
  foreach($parent['categories']['category'] as $category){
    $output .= '<li>'.$category['name'].'</li>';
    foreach($category['items']['item'] as $item){
      $output .= '<li>'.$item['name'].'</li>';
      // here is where the $item can have children w/ children
      // who can have children who can have children... etc... forever.
      // (i.e. $item['items']['item'] as $generation2_items++...)
      //
      // I want to add them as another <li></li>...
      //
      // How can you account for unknown # of children?
    }
  }
}
$output .= '</ul>';
echo $output;

代码 $outputs 类似如下的列表:

- parent 1
-- category 1
--- item 1 (gen 1)
---- sub item 1 (gen 2)
----- sub-sub item 1 (gen 3)
------- etc.
-------- etc.

如何确定每个项目的深度有多少子元素,然后如何创建足够的循环来相应地解析...或以其他方式迭代?

感谢您的帮助。

解决方案

PHP 递归函数解决了它。当我到达可能的无限重复部分时,这是我使用的:

function foo($element, $indent=0){
  $result .= '<li>';
  if($indent > 0){
    for($i=1;$i<=$indent;$i++){
      $result .= '&nbsp;&nbsp;&nbsp;&nbsp;';
    }
  }
  $result .= $element['name'].'</li>';
  if(isset($element['children']['child'])){
    $i++;
    foreach($element['children']['child'] as $child){
   $result .= foo($child, $i);
    }
  }
  return $result;
}    

$output .= foo($item);

【问题讨论】:

    标签: php xml arrays xml-parsing


    【解决方案1】:

    您可以为此使用recursive function。每个程序员都应该知道如何使用递归;如果你不这样做:继续学习吧!

    您基本上想要做的是创建一个函数,我们称之为foo(),它接受一个项目作为输入。 foo 会做两件事:

    1. 输出当前项
    2. 对于每个孩子,以孩子作为输入调用自身。

    正如我所说,创建递归函数非常有用,您应该学习和练习这个工具。例如,您可以向 foo 发送带有递归深度的第二个参数,以便您可以输出具有不同缩进的子项。

    【讨论】:

      【解决方案2】:

      在伪代码中,递归节点遍历函数可能如下所示:

      function traverse(node)
      {
          print(node);
      
          if(node.hasChildren()) {
              foreach(node.children as child) {
                  traverse(child);
              }
          }
      }
      

      希望对您有所帮助! :)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-06-25
        • 1970-01-01
        • 2012-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多