Okay, Now I have an unordered list here:
Ah, a fun little recursive exercise. I had a moment for this and here’s how I would do it. This works many levels deep recursively, but assumes that your data is not deep enough to explode the memory (recursion breaks in browsers if it is too deep). Should be fine for at least 10 levels or so.
I tested this out, seems it works, just save this in a HTML file and you should be fine.
Sorry there are not too many comments (well, technically speaking, none at all :) , this assumes you read jQuery and JS code fine. If you have questions, just ask in a comment and I’d be happy to explain.
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>Recursive list processor example</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var out = [];
function processOneLi(node) {
var aNode = node.children("a:first");
var retVal = {
"title": aNode.attr("title"),
"url": aNode.attr("href"),
"name": aNode.text()
};
node.find("> .children > li").each(function() {
if (!retVal.hasOwnProperty("children")) {
retVal.children = [];
}
retVal.children.push(processOneLi($(this)));
});
return retVal;
}
$("#mycustomid").children("li").each(function() {
out.push(processOneLi($(this)));
});
console.log("got the following JSON from your HTML:", JSON.stringify(out));
});
</script>
</head>
<body>
<ul id="mycustomid">
<li><a href="http://example.com/urlOfItemA" title="sometitle">Item A</a>
<ul class="children">
<li><a href="http://example.com/urlOfItemAChild1" title="sometitle">Child1 of A</a>
<ul class="children">
<li><a href="http://example.com/urlOfItemAGrandchild" title="sometitle">Grandchild of A</a>
<ul class="children">
<li><a href="http://example.com/urlOfItemAGrandGrandChild" title="sometitle">Grand Grand child of A</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="http://example.com/urlOfItemB" title="sometitle2">Item '"" B</a></li>
<li><a href="http://example.com/urlOfItemC" title="sometitle3">Item C</a></li>
</ul>
</body>
</html>
Seems like a recursive solution using one function for collections of list elements (children) and one for a list element would work. Note I'm assuming that you want it formatted as a string and that it's really represented as an array.
$(function() {
var json = formatListElements( $('#mycustomid > li') );
});
function formatListElements( elems )
{
var contents = []
$.each( elems, function( index, elem ) {
contents[index] = formatListElement( elem );
}
return '[' + contents.join(', ') + ']';
}
function formatListElement( elem )
{
var anchor = $(elem).children('a:first');
return '{ "name": "' + quote( anchor.text() )
+ '", "url": "' + quote( anchor.attr('href') )
+ '", "title": "' + quote( anchor.attr('title') )
+ '", "children": ' + formatListElements( $(elem).find('> ul > li')
+ '}';
}
function quote( str )
{
return str.replace( /"/g, '\\\"' );
}
The following source code is my solution. I think it's clear enough to show the principle to covert ul to json object. Good Luck :)
$(function() {
function buildJSON($li) {
var subObj = { "name": $li.contents().eq(0).text().trim() };
$li.children('ul').children().each(function() {
if (!subObj.children) { subObj.children = []; }
subObj.children.push(buildJSON($(this)));
});
return subObj;
}
var obj = buildJSON($("#ul-data").children());
$('body').append('<pre>').find('pre').append(JSON.stringify(obj, null, 2));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="ul-data">
<li><a href="#">AAA</a>
<ul>
<li><a href="#">DDD</a>
<ul>
<li><a href="#">EEE</a>
<ul>
<li><a href="#">FFF</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">BBB</a></li>
<li><a href="#">CCC</a></li>
</ul>
</li>
</ul>