我的目标是创建具有无限深度树的导航菜单。 我可以成功生成前 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和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树对元素的深入。"深度"(计数器)属性不是一个选项。因为,我在一个"推迟"的项目中面临着类似的问题,随着时间的推移,这个项目确实是无限的深度。
在程序样式上起作用的方法在函数中不起作用。 我最麻烦的方面是比较SimpleXML对象。大约有 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