Casey Becking
Casey Becking

Reputation: 137

Parse XML With jQuery

I have an XML that needs to be parsed using jQuery. I understand how to get the first level of site map nodes but some of my node are 3 or 4 levels deep. I can't seem to get past 2 level. Here is my XML and my code. I am tiring to output it to a list to be able to do a jQuery drop down on hover for one of the sites I'm working on. Please anyone who can help.

<siteMapNode url="#" title="root" description="">
    <siteMapNode url="http://qswebdev02:2010/Category/4-gear.aspx" title="Gear" description="Gear">
        <siteMapNode url="http://qswebdev02:2010/Category/5-snow.aspx" title="Snow" description="Snow">
            <siteMapNode url="http://qswebdev02:2010/Category/6-bags.aspx" title="Bags" description="Bags" />
        </siteMapNode>
        <siteMapNode url="http://qswebdev02:2010/Category/7-surf.aspx" title="Surf" description="Surf">
            <siteMapNode url="http://qswebdev02:2010/Category/8-towels.aspx" title="Towels" description="Towels" />
        </siteMapNode>
    </siteMapNode>
</siteMapNode>

-

$(document).ready(function () {
    $.ajax({
        url: 'nav.xml',
        type: 'GET',
        dataType: 'xml',
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            alert('Error: ' + textStatus + ", " + errorThrown);

        },
        success: function (xml) {
            var count = 0;

            $(xml).find('siteMapNode').each(function (e) {
                //category
                var url = $(this).attr('url');
                var title = $(this).attr('title');
                var descr = $(this).attr('description');
                var image = $(this).attr('image');
                var listItems = '<li id="parent"><a href="' + url + '">' + title + '</a></li>';

                if ($(this).children()) {
                    $(this).children().each(function (n) {
                        var suburl = $(this).attr('url');
                        var subtitle = $(this).attr('title');
                        var subdescr = $(this).attr('description');
                        var target = $(this).attr('target');
                        listItems += '<li id="' + subtitle + '" style="margin-left: 15px;"><a href="' + suburl + '" target="' + target + '" >' + subtitle + '</a></li>';
                    });

                }
                $(listItems).appendTo('#list');
                count++;
            });

        }
    });
});

Upvotes: 2

Views: 5032

Answers (2)

Casey Becking
Casey Becking

Reputation: 137

I think i figured it out using the recursion but making it even easier for my self

        $(document).ready(function() {
        var listitems = "";
        var rootNodes = $(xml).children();
        $(rootNodes).each(function(i) {
            listitems += parseNode($(this)[i]);
        });
        $('#thediv').html(listitems);
    });

    function parseNode(node) {
        var listitems = "";
        if ($(node).children().length > 0) {
            listitems += "<ul>";
            $(node).children().each(function(i) {
                var title = $(this).attr("title");
                var url = $(this).attr("url");
                listitems += "<li>" + title + "</li>";
                if ($(this).children().length > 0) {
                    listitems += parseNode($(this));
                }
            });
            listitems += "</ul>";
        }
        return listitems;
    }

Upvotes: 3

Stanislav M&#252;ller
Stanislav M&#252;ller

Reputation: 439

Here we go. This solution is using recursion, so now you are not bound anymore on the depth of your xml tree! Have fun :)

(function(){

  var returnA = function(a){
    var _this = a,
    url = _this.attr('url'),
    title = _this.attr('title'),
    description = _this.attr('description');

    return '<a href="'+url+'" title="'+description+'">' + title +'</a>';
  }

  var map = function(root) {
    var html = "<ul>";

    var _this = jQuery(root);

    if(root.length) {
     for (var i=0; i < root.length; i++) {

       var li = "<li>",

       child = jQuery(root[i]),
       subchildren = child.children(),
       returnedA = returnA(child);

       li += returnedA;

       if(subchildren.length) { li += arguments.callee(subchildren); }

       html += li+"</li>";

     };
    }

    return html+"</ul>";

  };

  var tree = map(jQuery('<siteMapNode url="#" title="root" description="">\
    <siteMapNode url="http://qswebdev02:2010/Category/4-gear.aspx" title="Gear" description="Gear">\
      <siteMapNode url="http://qswebdev02:2010/Category/5-snow.aspx" title="Snow" description="Snow">\
        <siteMapNode url="http://qswebdev02:2010/Category/6-bags.aspx" title="Bags" description="Bags" />\
      </siteMapNode>\
      <siteMapNode url="http://qswebdev02:2010/Category/7-surf.aspx" title="Surf" description="Surf">\
        <siteMapNode url="http://qswebdev02:2010/Category/8-towels.aspx" title="Towels" description="Towels" />\
      </siteMapNode>\
    </siteMapNode>\
  </siteMapNode>').children());
})();

PS: Your XML-Source looks corrupt to me, you need to close the tag of the root element.

Upvotes: 5

Related Questions