Skip to main content. Skip to secondary content (sidebar).

jQuery and XML revisited

Back in February of 2007 I wrote a post entitled Use jQuery expressions and AJAX to browse an XML file. The jQuery library has changed quite a bit since then, and I have decided to revisit jQuery and XML with an intermediate tutorial. Much of this tutorial is written as a response to questions I have received from other developers in regards to the February post. I hope you enjoy it.

In releasing jQuery v.1.2, a decision was made by the development team to drop XPath support from the core. Instead, an officially released XPath jQuery plugin is now available, which provides deprecated functionality. Although initially disappointed by this decision, I was happy to discover that alternative methods for obtaining data from an XML file are still available without the plugin.

The first code snippet begins with the jQuery equivalent of the window onload event, and then immediately following is the familiar $.ajax() implementation. I make a GET request for an XML file named dbug.xml, specify the return type as XML, then pass it through the success function as the variable xml. A ZIP file is available for download at the end of this post, and it contains the XHTML, JavaScript and XML file referenced here.

jQuery/Javascript:
$(function() {
    $.ajax({
        type: "GET",
        url: "dbug.xml",
        dataType: "xml",
        success: function(xml) {

            /* Count elements */

            var count = jXML.getCount(xml,{"Channel":"channel","Item":"item:has(title)","GUID":"guid[isPermaLink]:lt(3)"});
            alert( count["Channel"] + ", " + count["Item"] + ", " + count["GUID"] );

            /* Return objects with a specific attribute */

            var attribute = jXML.getAttribute(xml,{"GUID":["guid","isPermaLink",null],"Channel":["channel","id",null]});
            alert( attribute["GUID"] + ", " + attribute["Channel"] );

            /* Return objects with a specific attribute value */

            var attribute = jXML.getAttribute(xml,{"GUID":["guid","isPermaLink","false"],"Channel":["channel","id","channel_1"]});
            alert( attribute["GUID"] + ", " + attribute["Channel"] );

            /* Return a number of objects randomized */

            var random = jXML.getRandomObj(xml,{"Title":["item:has(title) > title",null],"URL":["item:has(link) > link",3]});
            for (i = 0; i < random["Title"].length; i++) {
                alert( $(random["Title"][i]).text() );
            }
            for (i = 0; i < random["URL"].length; i++) {
                alert( $(random["URL"][i]).text() );
            }

        }
    });
});

I will be using object literal notation in the tutorial, and the object that will process the XML is named jXML. There are three methods that exist in jXML: getCount, getAttribute, and getRandomObj. The second method (getAttribute) can perform two “functions”, depending on the parameters you pass through to it. The alerts are used only to let you know what type of response you are receiving back. In a production environment you would probably append this information to the DOM.

getCount

The getCount method will retrieve the number of element(s) that you specified from the XML. Each method, including getCount, really only takes two parameters: the xml reference, and a hash. The hash is also referred to as an associative array in Javascript. It is designated by an open curly brace, a key string in quotes, a colon, a value, and a close curly brace. Each key/value pair is separated by a comma. For example:

Javascript:
{"key":value,"key":value,"key":value}

With an associative array you can loop through values referencing the key, instead of an index. This works well for this tutorial, since the XML node names are distinct. Like indexed arrays, a hash value can be any data type, or object, including another array. In the first method getCount, a jQuery selector is used as a parameter value. However, in the other methods, an array containing several values is used as a parameter.

getAttribute

The getAttribute method retrieves only nodes (elements) as objects that contain a specific attribute. For instance, I want to find the guid node only if it contains an isPermaLink attribute. Leave the third value in the array null, or else you will be looking for an element with an attribute that also contains a specific value. The value that you want your attribute to contain would be this third value in the array.

The strings that are used as selectors in the example can be considered XPath substitutes, but any valid jQuery selector is appropriate. The following are only a few of the selectors that jQuery supports, and how each can be identified using plain English. To learn more about selectors supported by jQuery, you can visit the jQuery selector documentation page.

Get each guid node, or:

guid

Get each guid node that has an isPermaLink attribute with an index less than three, or:

guid[isPermaLink]:lt(3)

Get each item node that has a title child node, or:

item:has(title)

Get each title node that has an item parent node, or:

item > title

getRandomObj

The third, and most complicated method, will randomly select the number of and name of the node(s) that you specify. This method is great for a situation when any number of random elements are a sufficient data sampling. As opposed to the getAttribute method, which will alert “[Object object]“, the example demonstrates how to loop through the results returned. Remember, you are actually getting back an array object of objects, and you must loop through to each object individually.

jQuery/Javascript:
var jXML = {
    getCount: function(xml,nodes) {
        var response = {};
        for (var node in nodes) {
            response[node] = $(nodes[node],xml).length;
        }
        return response;
    },
    getAttribute: function(xml,nodes) {
        var response = {};
        for (var node in nodes) {
            if (nodes[node][2] == null) {
                response[node] = $(nodes[node][0] + "[" + nodes[node][1] + "]",xml);
            } else {
                if ($(nodes[node][0],xml).attr(nodes[node][1]) == nodes[node][2]) {
                    response[node] = $(nodes[node][0],xml);
                }
            }
        }
        return response;
    },
    getRandomObj: function(xml,nodes) {
        var response = {};
        for (var node in nodes) {
            var a = [];
            var b = [];
            $(nodes[node][0],xml).each(function(i) {
                b[i] = this;
            });
            var c = b.length;
            if (nodes[node][1] != null && nodes[node][1] < c) {
                c = nodes[node][1];
            }
            for (i = 0; i < c; i++) {
                var e = Math.floor(Math.random() * b.length);
                a[i] = b[e];
                b.splice(e,1);
            }
            response[node] = a;
        }
        return response;
    }
};

I will not walk through every detail of each method in the jXML object, but I will highlight a few commonalities between all the methods. Take a look at the getCount method, and pay special attention to the selector within the for loop. The nodes[node] snippet is a reference to the parameter passed through in the hash, which is then used as the actual selector. In this instance, it would be channel, item:has(title) and guid[isPermaLink]:lt(3).

In the other methods that take an array as the hash value, the syntax is slightly different. The addition of the brackets and an index number allows you to access specific elements in the array, such as nodes[node][1]. In the getAttribute method this is used to provide the attribute name that you wish to use in the selector, such as id and isPermaLink.

The final note is regarding the response sent back to the variable in each method call. To make it more manageable in development, the key/value pairs returned use the same keys as when passing the parameters. This prevents the mess of having to match up the keys sent with an indexed array returned. I tried to optimize getRandomObj as best as possible, but if anyone has suggestions, please share them in the comments.

Click here to download the code in this tutorial.

Tags: ,
Bookmark At Delicious

A day late and a dollar short... comments are closed.

01  |  September 25th, 2007 at 9:18 am

Hi there,

Great tutorial it’s definitely helped, however I’m struggling to create a live-search/auto-suggest/auto-complete/whatever that searches an xml file.

Any suggestions or even better could you please do another fantastic tutorial?

Many thanks

Comment by:

Alex

02  |  September 25th, 2007 at 10:35 am

Hi Alex,

I would suggest having a look at the jQuery plugins page. There are some great auto-complete plugins that already exist and that might suit your needs.

Brian

Comment by:

Brian

03  |  September 27th, 2007 at 4:33 pm

[...] jQuery and XML revisited » d’bug (tags: jquery xml javascript ajax tutorial development programming webdev **) [...]

Comment by:

links for 2007-09-28 « Simply… A User

04  |  September 30th, 2007 at 3:21 pm

[...] jQuery and XML revisited » d’bug (tags: jquery xml ajax tutorial webdev) [...]

Comment by:

links for 2007-09-30 « toonz

05  |  October 1st, 2007 at 12:33 pm

[...] JQuery xml (tags: blog.reindel.com 2007 mes9 dia1 at_tecp jquery xml blog_post) [...]

Comment by:

rascunho » Blog Archive » links for 2007-10-01

06  |  October 2nd, 2007 at 6:01 am

[...] jQuery and XML revisited Parse JSON with jQuery and JavaScript [...]

Comment by:

Ajaxian » Ajaxian Featured Tutorial: Parse JSON with jQuery and JavaScript

07  |  October 24th, 2007 at 1:28 am

I have to admit that this is a nice tutorial, but on my Internet Explorer it does absolutely nothing… no errors neither any result.
IE version is 6.0 on windows xp sp2

Comment by:

Bruno

08  |  October 24th, 2007 at 2:59 am

Hi Bruno,

Are you using the IE6 downloaded from Evolt.org, IE6 from “Multiple IE”, or a computer simply with IE6 installed? The reason I ask is that in standalone IE6 from Evolt.org, ActiveX is not supported, which would explain why it is not working. I hope I can be of some assistance.

Comment by:

Brian

09  |  November 2nd, 2007 at 12:27 pm

[...] jQuery and XML Revisited. Brian Reindel walks through a few methods he wrote to handle XML retrieved via xhr. [...]

Comment by:

Learning jQuery » Tutorials Elsewhere

10  |  November 5th, 2007 at 5:27 pm

[...] jQuery and XML revisited » dâ��bug - [...]

Comment by:

mulling.net

11  |  January 24th, 2008 at 11:03 am

What fun! I never realized you could use jQuery to search through XML documents like this. I’m very glad you posted this :)

Comment by:

Brian S

12  |  February 10th, 2008 at 10:27 pm

Great tutorial, but I’ll have to echo Bruno’s comment — it’s not working for me on IE6. ActiveX is definitely supported and enabled, but still no luck….

Comment by:

Kevin

13  |  March 18th, 2008 at 5:36 am

It’s a nice jquery functionality, it will be nice to see more about the “get content” inside each xml tag

Comment by:

Martin Sarsini

14  |  March 18th, 2008 at 5:42 am

For Bruno and Kevin, for me it wasn’t working either.
Perfect on Firefox, not working on IE.
The XML file didn’t had the right headers, save the file in .xml or if generated by php add header(”Content-type: application/xml”)

Comment by:

Martin Sarsini

15  |  March 20th, 2008 at 3:26 am

Hi Martin,

Thanks for commenting and for sharing that fix!

Brian

Comment by:

Brian

16  |  March 24th, 2008 at 2:47 am

[...] jQuery and XML revisited Parse JSON with jQuery and JavaScript [...]

Comment by:

jQuery.getJSON « Mashuphowto’s Weblog

17  |  April 2nd, 2008 at 4:05 am

[...] with jQuery 25. JQuery Pop-up Menu Tutorial 26. A Quick Code Igniter and JQuery Ajax Tutorial 27. jQuery and XML revisited 28. What is JSONP? 29. Creating A Sliding Image Puzzle Plug-In 30. Slide out and drawer effect 31. [...]

Comment by:

65 Excellent jQuery Resources (tutorials,cheat sheets,ebooks,demos,plugins…) | Speckyboy - Wordpress and Design

18  |  June 15th, 2008 at 10:46 pm

Hi,

I have a problem in IE, I saw all the comments and I have the right headers.

Also, I downloaded the code from here, but it’s not working in IE7 (Vista and XP).

so what should I do ?

Comment by:

Khaled

19  |  July 21st, 2008 at 1:16 am

[...] with jQuery 25. JQuery Pop-up Menu Tutorial 26. A Quick Code Igniter and JQuery Ajax Tutorial 27. jQuery and XML revisited 28. What is JSONP? 29. Creating A Sliding Image Puzzle Plug-In 30. Slide out and drawer effect 31. [...]

Comment by:

20 Amazing jQuery Plugins and 65 Excellent jQuery Resources | Speckyboy - Wordpress and Design