In early 2009, I experimented with XML based iPhone / Safari Mobile web app which used jQuery to parse and traverse multiple levels of nodes in an XML file and display the data. While that project never panned out, the core code has become quite useful in a number of professional and personal projects. This tutorial provides working examples and demonstrates the concept of parsing and traversing an XML file with jQuery using AJAX.
The demo has been updated to improve performance and now includes zebra striping
The XML
First, lets take a look at the XML structure:
In it’s most basic form, the XML file contains the main <data> node with subsequent <entry> nodes. Within each entry we are defining the meta data such as <date>, <cost> and <category>. Also within the entry are a <name> and <description> field which are wrapped in CDATA blocks that will allow us to use special characters and punctuation without compromising the validity of the XML file.
AJAX
Using jQuery’s wonderfully simple AJAX method to make an XMLHttpRequest. The basic code for making the AJAX request for the example XML file shown below:
$.ajax({
type: 'GET',
url: 'xml/data.xml',
dataType: 'xml',
success: function(xml_list) {
$(xml_list).find('entry').each(function() {
var xml_date = $(this).attr('date');
var xml_cost = $(this).attr('cost');
var xml_category = $(this).attr('category');
var xml_name = $(this).find('name').text();
var xml_description = $(this).find('description').text();
}
});
The first two things to note in the code are the dataType and success parameters. We use dataType to specify that we are requesting an XML fie and using a function in success to manipulate and display the XML data. Next, we use jQuery’s super handy find() method to search the XML document for entry nodes. We then chain the each() function to iterate through the data that is returned from the find(). Next, variables are created for each of the items we will be displaying. Using variables as opposed to the selector name caches the data so that it is not called in each iteration. Note that there are two methods of assigning the variables in this example; the first simply assigns available attributes to the variables while the second has to traverse one step deeper to return the values of the name and description nodes.
Making it work
At this point we’ve covered the basic concepts but it is time to actually do something practical with the data. Displaying the results in HTML is easy but while we’re writing the markup, lets add some placeholders for filtering the data.
Date Name Description Category $
Ignore the <UL> for now and notice that we are adding elements to the the <thead> but not the <tbody>. Jump back to the JavaScript file and add this line below the var declaration for description and add:
$('<tr filterCriteria= "'+ xml_cost +'"></tr>')
.html('
'+ xml_date +'
'+ xml_name +'
'+ xml_description +'
'+ xml_category +'
$'+ xml_cost +'
')
.appendTo(wrapper +' table tbody');
This line is in our loop so it will iterate a populated <tr> for each entry in our XML and append it to the <tbody></tbody> of the table.
Making it useful
The parser is now built and displays the data from our XML file but it lacks practicality. What if you want to sort by Computer Accessories? What if you want to show all items less than $20? These start to become serious issues as the length of the XML document increases.
We will cheat a little bit and tie in Christian Bach’s incredibly useful tablesorter jQuery plugin to do the sorting in this example. I won’t go into detail on the options and uses of this plugin because they are already covered thoroughly on the tablesorter plugin site.
Filtering is done by simply using jQuery’s hide() and show() on specifically tagged table rows. We’ve already created the HTML in previous steps so all that is left is to assign a onClick event and add a switch to create the filter. To add sorting to the table we’ve created add the following after the each() function inside the AJAX call:
window.setTimeout('$("'+ wrapper +' table").tablesorter({sortList:[[0,0],[0,0]], widgets: [\'zebra\']});', 120);
The selector is wrapped in an interval because both the tablesorter script call and our AJAX call happen concurrently on page load which causes the tablesorter to fire before the table is fully populated with or XML. The 120ms on the interval is somewhat arbitrary and it can be changed as needed. Additionally, if you prefer not to use the interval, you might be able to do so depending on your particular use and XML file size. Also, note the use of the “zebra widget” option; this will assign a “stripe” class to odd numbered rows which allows for alternate row background colors.
var nav_link = $('#xml_nav li a');
nav_link.click( function() {
var tr = wrapper +' table tbody tr';
$(tr).show(); //Show all rows
switch ($(this).attr("class")) {
case "filter_10 hit" :
$(tr).filter(function (index) {
return parseFloat($(this).attr('filterCriteria')) > 10;
}).hide();
break;
case "filter_10_20 hit" :
$(tr).filter(function (index) {
return parseFloat($(this).attr('filterCriteria')) < 10 || parseFloat($(this).attr("filterCriteria")) > 20 ;
}).hide();
break;
case "filter_20 hit" :
$(tr).filter(function (index) {
return parseFloat($(this).attr('filterCriteria')) < 20;
}).hide();
break;
case "filter_0 hit" :
$(tr).show();
break;
}
/* Remove all instances of the stripe (alternating row) class
Then re-apply stripe class as to visible alternating rows
*/
$(tr).removeClass('stripe');
$(tr + ':visible:odd').addClass('stripe');
});
In a previous step we generated the HTML that is inserted into our table and you might have noticed an attribute was added to the cost <td> called filterCriteria. The code above uses the value of this attribute to determine which items to show / hide. Obviously, this will only work if the value of cost is an integer. Feel free to develop a more elegant solution.
Finishing up
The last step that I will cover is adding a simple preloader to display as AJAX grabs the XML data. At the top of the function place the following line:
$('
').html('
Loading Data...
').prependTo($('body'));
Inside of the xml_parser() function in the AJAX call’s success parameter place these two lines:
$('#preload_xml').remove();
$(wrapper).show();
Thes four lines of code will first hide our wrapper div and then dynamically construct a div with a loading message and then remove the code from the page once everything is loaded and finally show the wrapper again.
We now have a parser that sorts and filters XML data. There are many other features that could be added such as a more complex content filter and code cleanup to make things even more re-usable. If you find this code useful and decide to use it in your projects, I encourage you to modify the code as you find necessary and please feel free to share your examples.
Other Considerations
There is a great jQuery XML parser plugin called jParse which can be used to grab display the contents of an XML file with little effort. Other than the reliance on AJAX to call the XML file, the approach used by jParse differs considerably from the approach that I took in this article. If you are looking strictly for XML display, I recommend looking into jParse.





