我的目标是创建具有无限深度树的导航菜单。我可以成功生成前2个级别。第一个(顶级)使用的是未存储在XML文件中的PHP数组。第二个是从平面xml文件生成的。主要问题是成功的递归。
这是XML结构:
<articles>
<article>
<menu parent="Insurance" label="Business" target="#" show="true" />
<data />
<body />
</article>
<article>
<menu parent="Resources" label="Videos" target="content.php#videos" show="true" />
<data />
<body />
</article>
<article>
<menu parent="Business" label="Disability" target="content.php#disability" show="true" />
<data />
<body />
</article>
<article>
<menu parent="Business" label="Liability" target="content.php#liability" show="true" />
<data />
<body />
</article>
</articles>
我在目标属性中使用#来确定是否需要启动新列表(子菜单)。
我通过输出正确信息获得成功的PHP代码是:
$objXMLMenu = simplexml_load_file('menu.xml');
foreach ($mainmenu as $menuparent) { //Main Array
echo "<li><a href=\"" .$maintargets[$i]. "\">". $menuparent ."</a>\n"; // Top Menu array. I use 2 for clarity
if ($maintargets[$i] == "#"){
//Open the ULs for filling
echo "\t<ul>\n";
// Start function here?
foreach($objXMLMenu->article as $art){
foreach($art->menu as $menuitem){
if($menuitem['parent'] == $menuparent){ //Compare to Main Array
if ($menuitem['show'] == "true"){
if($menuitem['target'] == "#"){ //A Submenu exits here
echo "\t\t<li><a href=\"" . $menuitem['target'] . "\" >" .$menuitem['label'] . "</a></li>\n";
echo "\t\t\t<ul>\n";
//Run XMLQUERY match? As a
echo "\t\t\t</ul>\n";
}else{
echo "\t\t<li><a href=\"" . $menuitem['target'] . " \"rel=\"ajax\">" .$menuitem['label'] . "</a></li>\n";
}
}
}
}
}
//Close Middle Menus
echo "\t</ul>";
}
$i++;
//close Top Level Menu Item
echo "</li>\n";
}
//<UL> Footer
echo "\t</ul>\n</div>\n";
为了使它成为一个递归函数,我收到了第一个foreach语句的错误,这表明我应该切换到DOM&amp; XPATH而不是simplexml。这是我到目前为止所提出的功能:
$objXMLMenu = simplexml_load_file('menu.xml');
// Start function here!
function mysubmenu($menuparent){
foreach($objXMLMenu->article as $art){
foreach($art->menu as $menuitem){
if($menuitem['label'] == $menuparent){
//Compare to Main Array
if ($menuitem['show'] == "true"){
if($menuitem['target'] == "#"){
// ((ROOT)
//A Submenu exits here
$strResponse .= "\t\t<li><a href=\"" . $menuitem['target'] . " \">" .$menuitem['label'] . "</a></li>\n";
$strResponse .= "\t\t\t<ul>\n";
//xmlpath QUERY instead?
mysubmenu($menuitem['parent']);
$strResponse .= "\t\t\t</ul>\n";
}else{
$strResponse .= "\t\t<li><a href=\"" . $menuitem['target'] . " \"rel=\"ajax\">" .$menuitem['label'] . "</a></li>\n";
}
}
}
}
//insert counter to stop foreach loop after all records are posted.
}
return $strResponse;
} //End Function
这种类型的递归对我来说是一个新的界限。我发现的每个例子或解释都涉及到XML树更深入到元素中。 “深度”(计数器)属性不是一个选项。因为,我在一个“推迟”的项目中面临着类似的问题,这个项目确实是一段时间内无限的深度。
答案 0 :(得分:0)
在程序样式上工作的东西在函数中不起作用。我最令人不安的方面是comparing SimpleXML objects。大约有5行需要更改。对于更长的递归,可能有一种更简单,更快速的方法来获得这个答案。但我发现这个目前有效。
function mysubmenu($menuparent){
$objXMLMenu = simplexml_load_file('menu.xml');
foreach($objXMLMenu->article as $art){
foreach($art->menu as $menuitem){
if((string)$menuitem['parent'] == $menuparent){
if ($menuitem['show'] == "true"){
if($menuitem['target'] == "#"){
echo "\t\t<li><a href=\"" . $menuitem['target'] . "\">" .$menuitem['label'] . "</a></li>\n";
echo "\t\t\t<ul>\n";
mysubmenu($menuitem['label']);
echo "\t\t\t</ul>\n";
}else{
echo "\t\t<li><a href=\"" . $menuitem['target'] . "\" rel=\"ajax\">" .$menuitem['label'] . "</a></li>\n";
}
}
}
}
}
} //End Function