我有一个小应用程序执行以下操作:
问题是每个项目都可以生孩子,他们可以生孩子,可以生孩子......等等,这可以无限期地继续下去。
如何在最终输出中包含孩子的每个孩子?
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;
代码$输出类似于:
的列表- 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 .= ' ';
}
}
$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);
答案 0 :(得分:3)
您可以使用recursive function。每个程序员都应该知道如何使用递归;如果你不这样做:继续学习吧!
你基本上想要做的是创建一个函数,让它称之为foo()
,它将一个项目作为输入。 foo
会做两件事:
正如我所说,创建递归函数非常有用,你应该学习并运用这个工具。例如,您可以使用递归的深度向foo
发送第二个参数,以便输出具有不同缩进的子项。
答案 1 :(得分:1)
在伪代码中,递归节点遍历函数可能如下所示:
function traverse(node)
{
print(node);
if(node.hasChildren()) {
foreach(node.children as child) {
traverse(child);
}
}
}
希望有所帮助! :)