Reputation: 2914
I am trying to convert a nested xml document to an unordered list using jquery.The xml document is
<?xml version="1.0" encoding="utf-8"?>
<Parent>
<name>Director</name>
<Children>Exe Director1</Children>
<Children>Exe Director2</Children>
<Parent>
<name>Exe Director3</name>
<Children>Sub Director 1</Children>
<Children>Sub Director 2</Children>
<Parent>
<name>Sub Director 3</name>
<Children>Cameraman 1</Children>
<Children>Cameraman 2</Children>
</Parent>
</Parent>
</Parent>
The expected output:
<ul>
<li>Director
<ul>
<li>Exe Director 1</li>
<li>Exe Director 2</li>
<li>Exe Director 3
<ul>
<li>Sub Director 1</li>
<li>Sub Director 2</li>
<li>Sub Director 3
<ul>
<li>Cameraman 1</li>
<li>Cameraman 2</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
The output which I am getting.
<ul>
<li>Director</li>
<ul>
<li>Exe Director1</li>
<li>Exe Director2</li>
<li>Exe Director3</li>
<ul>
<li>Sub Director 1</li>
<li>Sub Director 2</li>
<li>Sub Director 3</li>
<ul>
<li>Cameraman 1</li>
<li>Cameraman 2</li>
</ul>
</ul>
</ul>
</ul>
As you can see,the Children are not getting created inside the parent li
but outside it
The latest version of the code
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
var levels;
$(document).ready(function()
{
$.ajax({
type: "GET",
url: "test.xml",
dataType: "xml",
success: function (xml) {
var $ul = xmlParser(xml, $('#ListContainer'));
}
});
});
function xmlParser(xml,ul) {
$(xml).contents().each(function (i, el)
{
if (el.nodeName.toUpperCase() == "CHILDREN")
{
$("<li>").text($(el).text()).appendTo($('ul:last')); // Append <li> Children
} else if (el.nodeName.toUpperCase() == "NAME")
{
$('<li>').text($(el).text()).appendTo(ul);
$('<ul>').insertAfter($("li:last"));
}
else if (el.nodeName.toUpperCase() == "PARENT")
{
if($('ul').length == 0)
{
ul = ul.append('<ul>');
}
ul.append(xmlParser($(el),$("ul:last") )); // Recursively append the other Parent
}
});
return ul;
}
</script>
</head>
<body>
<div id="ListContainer"></div>
</body>
</html>
I am breaking my head over this code.Can you guys help me out with what might be going wrong!
Thanks
Upvotes: 1
Views: 2152
Reputation: 52
You are appending PARENT element to same "ul" element for all "PARENT" contents. use
$ul.find('li').last().append(xmlParser($(el)));
instead of
$ul.append(xmlParser($(el)));
Upvotes: 0
Reputation: 3045
Here is Consolidation of my comments into a coherent answer-->
$("#ListContainer").append($ul);
out of recursion; <UL>
outside xmlParser()
method and pass it as parentElem.
e.g. var $ul = xmlParser(xml, $('<ul>')); $("#ListContainer").append($ul)
(in success callback of $.ajax)$ul
as output result of xmlParser()
functionUpvotes: 1
Reputation: 7157
My suggestion is to use jQuery's map function recursively, as in the following example:
<script type="text/javascript">
$(function() {
var map = function() {
if ($(this).is("parent")) {
var children = $(this).children().map(map).get().join('');
$(this).children().remove();
var result = "<li>" + $(this).text();
return result + "<ul>" + children + "</ul></li>";
}
if ($(this).is("Children")) {
return "<li>" + $(this).text() + "</li>";
}
};
$.get("test.xml", function(data) {
var result = $(data).map(map);
$("div").html("<ul>" + result[0] + "</ul>");
}, "html");
});
</script>
This ensures that the input tree is traversed completely, and that the resulting output has the same "indentations" as the input.
Notice that map()
returns an array, so the resulting string is present as the first item of the array.
Upvotes: 1
Reputation: 2281
You are appending PARENT element to same "ul" element for all "PARENT" contents. use
$ul.find('li').last().append(xmlParser($(el)));
instead of
$ul.append(xmlParser($(el)));
refer below link for last api:
Upvotes: 1