I have the following menu:
<ul id="myMenu" >
<li><a href="#" >Home</a></li>
<li><a href="#">Services</a>
<ul>
<li><a href="#">Residential</a>
<ul>
<li><a href="">Sub Page 1</a></li>
<li><a href="">Sub Page 2</a></li>
</ul>
</li>
<li><a href="#">Commercial</a></li>
</ul>
</li>
<li><a href="#">Prices</a></li>
<li><a href="#">Contact Us</a></li>
</ul>
I want to convert this HTML menu to an array or a JSON (I'd prefer JSON format) to be something like this:
"menu" : [
{
"title" : "Home",
"href" : "blabla.com"
}
,
{
"title" : "Service",
"href" : "blabla.com",
"pages" :
[
{
"title" : "Residential",
"href" : "blabla.com",
"pages" : [
{
"title" : "Sub Page1",
"href" : "blabla.com",
},
{
"title" : "Sub Page2",
"href" : "blabla.com",
}
]
}
]
},
{
"title" : "Prices",
"href" : "blabla.com"
},
{
"title" : "Contact Us",
"href" : "blabla.com"
}
]
I use the following function to convert HTML to an array (I know this is complicated to do, so, You don't need to implement it, It's ready to use):
function xmlstr_to_array($xmlstr)
{
$doc = new DOMDocument();
$doc->loadHTML($xmlstr);
return domnode_to_array($doc->documentElement);
}
function domnode_to_array($node) {
$output = array();
switch ($node->nodeType)
{
case XML_CDATA_SECTION_NODE:
case XML_ATTRIBUTE_NODE:
//If it's only Text
case XML_TEXT_NODE:
$output = trim($node->textContent);
break;
//If it's an xml node, then search for children
case XML_ELEMENT_NODE:
for ($i = 0, $m = $node->childNodes->length; $i < $m; $i++)
{
$child = $node->childNodes->item($i);
$v = domnode_to_array($child);
if(isset($child->tagName))
{
$t = $child->tagName;
if(!isset($output[$t]))
{
$output[$t] = array();
}
//Eliminate li please
if ($t == 'li')
{
$output[$t][] = $v;
}
else
{
$output[$t][] = $v;
}
}
else if($v)
{
$output['title'] = (string) $v;
$output['href'] = 'blablabla.com';
}
}
if(is_array($output))
{
if($node->attributes->length) {
$a = array();
foreach($node->attributes as $attrName => $attrNode) {
$a[$attrName] = (string) $attrNode->value;
}
// $output['@attributes'] = $a;
}
foreach ($output as $t => $v) {
if(is_array($v) && count($v)==1 && $t!='@attributes') {
// $output[$t] = $v[0];
$output[$t] = $v[0];
}
}
}
break;
}
return $output;
}
I tried to use something like this to parse the whole array (and convert it later to JSON) but I faild:
function parse($data)
{
$arr = [];
//Rules
// ul = there's a sub-page
$i = 0;
foreach ($data as $conv)
{
foreach ($conv as $k => $v)
{
//if <a> then it means it's an item. since all items starts with <a>
if (isset($v['a']))
{
$arr[$i] = $v['a'];
if (isset($v['a']['ul']))
{
}