My objective is to create navigation menu that has unlimited depth tree. I can successfully generate the top 2 levels. The first (Top level) is using a PHP array that is not stored within the XML file. The second is generated from a flat xml file. The main problem is successful recursion.
Here is the XML structure:
<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>
I am using # in my target attribute to identify if a new list (sub-menu) needs to be started.
The PHP code that I receive success with outputting the correct information is:
$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";
In an attempt to make it a recursive function I receive an error with my 1st foreach statement, which suggests to me I should switch to DOM & XPATH instead of simplexml. Here is the function I’ve come up with so far:
$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
Recursion of this type is a new boundary for me. Every example or explanation I have found involves XML tree’s going deeper into the elements. A “depth” (counter) attribute is not an option. Since, I am facing a similar problem on a “postponed” project that truly is unlimited depth over time.
What worked on the procedural style did not work in the function. My most troubling aspect was in comparing SimpleXML objects. There are about 5 lines that needed to be changed. There is probably a simpler and faster way to get to this answer though for longer recursions. But I found this works for now.