XML Parsing with jQuery

Skill

XML Parsing with jQuery

Posted in:

XML is an important part of AJAX. Heck, it's right in the name, "Asynchronous JavaScript and XML", so knowing how to parse XML is equally important. This tutorial will demonstrate how to parse XML using jQuery that should cover almost all cases you'd typically run into.

Using jQuery to parse XML is vaguely reminiscent of LINQ in the recent .NET frameworks. That's a good thing, since LINQ made parsing XML in .NET vastly easier than previous techniques. With jQuery, when you receive XML from a callback, you're not actually getting raw text, you're actually getting a DOM (document object model) that jQuery can traverse very quickly and efficiently to give you the data you need.

Let's start by looking at the example XML document we'll be parsing today. I made a file that contains most things you'd see in a typical XML document - attributes, nested tags, and collections.

<?xml version="1.0" encoding="utf-8" ?>
<RecentTutorials>
  <Tutorial author="The Reddest">
    <Title>Silverlight and the Netflix API</Title>
    <Categories>
      <Category>Tutorials</Category>
      <Category>Silverlight 2.0</Category>
      <Category>Silverlight</Category>
      <Category>C#</Category>
      <Category>XAML</Category>
    </Categories>
    <Date>1/13/2009</Date>
  </Tutorial>
  <Tutorial author="The Hairiest">
    <Title>Cake PHP 4 - Saving and Validating Data</Title>
    <Categories>
      <Category>Tutorials</Category>
      <Category>CakePHP</Category>
      <Category>PHP</Category>
    </Categories>
    <Date>1/12/2009</Date>
  </Tutorial>
  <Tutorial author="The Tallest">
    <Title>Silverlight 2 - Using initParams</Title>
    <Categories>
      <Category>Tutorials</Category>
      <Category>Silverlight 2.0</Category>
      <Category>Silverlight</Category>
      <Category>C#</Category>
      <Category>HTML</Category>
    </Categories>
    <Date>1/6/2009</Date>
</Tutorial>
  <Tutorial author="The Fattest">
    <Title>Controlling iTunes with AutoHotkey</Title>
    <Categories>
      <Category>Tutorials</Category>
      <Category>AutoHotkey</Category>
    </Categories>
    <Date>12/12/2008</Date>
  </Tutorial>
</RecentTutorials>

The first thing you're going to have to do is write some jQuery to request the XML document. This is a very simple AJAX request for the file.

$(document).ready(function()
{
  $.ajax({
    type: "GET",
    url: "jquery_xml.xml",
    dataType: "xml",
    success: parseXml
  });
});

Now that that's out of the way, we can start parsing the XML. As you can see, when the request succeeds, the function parseXML is called. That's where I'm going to put my code. Let's start by finding the author of each tutorial, which are stored as attributes on the Tutorial tag.

function parseXml(xml)
{
  //find every Tutorial and print the author
  $(xml).find("Tutorial").each(function()
  {
    $("#output").append($(this).attr("author") + "<br />");
  });

  // Output:
  // The Reddest
  // The Hairiest
  // The Tallest
  // The Fattest
}

The quickest way to parse an XML document is to make use of jQuery's powerful selector system, so the first thing I do is call find to get a collection of every Tutorial element. Then I call each, which executes the supplied function on every element. Inside the function body, this now points to a Tutorial element. To get an attribute's value, I simply call attr and pass it the name of what attribute I want. In this example, I have a simple HTML span object with an id of "output". I call append on this element to populate it with data. You would probably do something a little more exciting, but I just wanted a simple way to display the results.

See how easy that is? Let's now look at a slightly more complicated one. Here I want to print the publish date of each tutorial followed by the title.

//print the date followed by the title of each tutorial
$(xml).find("Tutorial").each(function()
{
  $("#output").append($(this).find("Date").text());
  $("#output").append(": " + $(this).find("Title").text() + "<br />");
});

// Output:
// 1/13/2009: Silverlight and the Netflix API
// 1/12/2009: Cake PHP 4 - Saving and Validating Data
// 1/6/2009: Silverlight 2 - Using initParams
// 12/12/2008: Controlling iTunes with AutoHotkey

This is very similar to the previous example, except now the values are stored inside element text instead of attributes. Again, I want to go through every Tutorial tag, so I first use find and each. Once I'm inside a Tutorial, I need to find the Date, so I use find again. To get the text inside an XML element, simply call text. I repeat the same process again for the Title, and that's it.

We've now parsed every piece of information except the categories that each tutorial belongs to. Here's the code to do that.

//print each tutorial title followed by their categories
$(xml).find("Tutorial").each(function()
{
  $("#output").append($(this).find("Title").text() + "<br />");

  $(this).find("Category").each(function()
  {
    $("#output").append($(this).text() + "<br />");
  });

  $("#output").append("<br />");
});

// Output:
// Silverlight and the Netflix API
// Tutorials
// Silverlight 2.0
// Silverlight
// C#
// XAML

// Cake PHP 4 - Saving and Validating Data
// Tutorials
// CakePHP
// PHP

// Silverlight 2 - Using initParams
// Tutorials
// Silverlight 2.0
// Silverlight
// C#
// HTML

// Controlling iTunes with AutoHotkey
// Tutorials
// AutoHotkey

Once again, I get every Tutorial by using find and each. I then get the Title in the same was as the previous example. Since a tutorial can belong to several categories, I call find and each to iterate over each Category element inside a tutorial. Once I'm inside a Category element, I simple print out its contents using the text function.

Being able to parse elements, attributes, and collections should cover almost every form of XML you'd ever see, and making use of jQuery selectors to get the job done makes parsing XML in JavaScript a breeze. That does it for this tutorial. Hopefully we all learned something about jQuery and XML.

tsantos
01/14/2009 - 09:37

Very nice post

reply

Zach
01/16/2009 - 11:23

Be wary of namespaces!

http://www.zachleat.com/web/2008/05/10/selecting-xml-with-javascript/

reply

The Reddest
01/16/2009 - 12:49

Thanks for the warning! Unfortunately, I didn't think about namespaces when I wrote the article. I guess I should have mentioned somewhere that jQuery doesn't directly support them.

reply

johntantalo
01/16/2009 - 13:07

success: function(xml) { parseXml(xml); } should be success: parseXml

reply

The Reddest
01/16/2009 - 13:21

You're definitely right about that. I'll blame that on a copy/paste error. Where I was using this code I had an another function call in that body. I've corrected the post. Thanks for finding it.

reply

khautinh
03/13/2009 - 15:12

can anyone help me to read this xml file please?  I just took over from the previous developer.
courses
  <coursetitle> math
    <coursetime> 1:00pm </coursetime>
    <coursetime> 3:00pm </coursetime>
  </coursetitle

  <coursetitle> phisic
    <coursetime> 1:00pm </coursetime>
    <coursetime> 3:00pm </coursetime>
  </coursetitle>
</courses>

It was using javascript to read before.  I though that JQuery may do a better job so I do this for my learning curve with JQuery.
Thanks for helps

reply

The Reddest
03/13/2009 - 15:20

Try posting the comment again. use the [xml] language tag.

reply

Anonymous
03/16/2009 - 18:12

can anyone help me to read this xml file please? I just took over from the previous developer.
1. I like to load course into the drop down box1 with the course
2. If user click on the course, it populate the time into drop down box2.

<courses>
 <course>math
   <time>1:00pm</time>
   <time>3:00pm</time>
 </course>
 <course>phisic
   <time>1:00pm</time>
   <time>3:00pm</time>
 </course>
</courses>

It was using javascript to read before. I though that JQuery may do a better job so I do this for my learning curve with JQuery.

Since I resend this question.
Thanks for helps

reply

Sascha
03/30/2009 - 02:32

Restructure your Xml-File like this:

<courses>
 <math>
   <time>1:00pm</time>
 </math>
 <math>
   <time>3:00pm</time>
 </math>
 <phisic>
   <time>1:00pm</time>
 </phisic>
 <phisic>
   <time>3:00pm</time>
 </phisic>
</courses>

You can access the xml tags with the following jQuery code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>XML Parsing With jQuery</title>
    <script src="jquery-1.2.6.js" type="text/javascript"></script>

 
 <script type="text/javascript">
   
    $(document).ready(function()
      {
          <!-- math -->
        $.get('myData.xml', function(d){
        var options="";
        $(d).find('math').each(function(){
                        var $time = $(this);
            var dropdownvalue = $time.find('time').text();
            options += ' <option value="' + dropdownvalue + '">' + dropdownvalue + '</option>\r\n'
        })
                $("#mymath").html(options);
                ;
                });
                <!-- math End -->
                <!-- phisic -->
        $.get('myData.xml', function(d){
        options="";
        $(d).find('phisic').each(function(){
                        var $time = $(this);
            var dropdownvalue = $time.find('time').text();
            options += ' <option value="' + dropdownvalue + '">' + dropdownvalue + '</option>\r\n'
        })
                $("#myphisic").html(options);
                ;
                });
                <!-- phisic End -->
});
    </script>
       

</head>
<body>
                        <select name="mymath" id="mymath">
                        <option value="1">mymath</option>
                        <select name="myphisic" id="myphisic">
                        <option value="1">myphisic</option>
</body>
</html>

reply

Dario
07/06/2009 - 15:28

Don't work with IE :(

reply

robmar427
09/24/2009 - 10:44

i am making a video gallery. i found a flash template that creates xml file.

XML data looks this:

<?xml version="1.0"?>
<content>
    <gallery Name="All Videos">
        <video Thumb="Signs/400thumb.jpg" VideoClip="Signs/400.flv" Title="400" Copy="0:24:41"/>
        <video Thumb="Signs/moneythumb.jpg" VideoClip="Signs/Money.flv" Title="Blood Money" Copy="0:16:45"/>
        <video Thumb="Dag/fdsthumb.jpg" VideoClip="Dag/friends.flv" Title="Friend Under" Copy="0:22:18"/>
        <video Thumb="Dag/rocky.jpg" VideoClip="Dag/Rocking_Throne.flv" Title="Rocking The King's Throne" Copy="0:36:40"/>
    </gallery>

The gallery works. When I click each thumbnails, the FLV runs.

I want to put film description in my markup. How will i do this for every film currently running?

Thank you...

reply

Michael
11/22/2009 - 01:26

I get confused at:

function parseXml(xml)
{
  //find every Tutorial and print the author
  $(xml).find("Tutorial").each(function()

where is the parameter/variable "xml" declared and instantiated with jquery_xml.xml? Does it magically inherit it from the ajax request. Could someone explain this for me?

reply

The Reddest
11/23/2009 - 09:29

the xml variable is passed into the function automatically by jQuery. parseXml is supplied to jQuery as part of the ajax request.

reply

petrus
01/26/2010 - 05:02

Hi, thanks for this tutorial it has been illuminating.

I'v just one problem - it takes about 6-12 seconds to parse.. :( please help, here is my situation:

XML example: (XML is dynamically created)

<?xml version="1.0" encoding="utf-8"?>
<RESPONSE xsi:noNamespaceSchemaLocation="http://192.168.xxx.xx:10000/rest/schemas/contacts_response.xsd">

<PARAMETERS>
<Ret_Data>
<contact url="http://192.168.xxx.xx:10000/rest/contact/1">
  <CNT_ID>1</CNT_ID>
  <CNT_LASTNAME>Marko</CNT_LASTNAME>
  <CNT_FIRSTNAME>Matic</CNT_FIRSTNAME>
  <CNT_ORGANIZATIONNAME>IT Business Soft</CNT_ORGANIZATIONNAME>
  <CNT_TYPE>1</CNT_TYPE>
  <CNT_NAME>Marko Matic</CNT_NAME>
  </contact>

  <contact url="http://192.168.xxx.xx:10000/rest/contact/14044">
   ...
  </contact>
   ...
   ... etc (about 1500 CONTACT elements)
 
   </Ret_Data>
</PARAMETERS>

(there are about 1500 'contact' nodes) -> IS IT POSSIBLE THAT IT'S SLOW BECAUSE EACH WILL ITERATE TROUGH EVERY CHILD - CAN I RESTRICT SOMEHOW SOMETHING?)

 
$(document).ready(function()
{
 $.ajax({                  
   type: "GET",
   url: "http://192.168.xxx.xx:10000/rest/contacts/",
   dataType: "xml",
   success: parseXML,
   error: err    
        });              
});    
function err(xhr, reason, ex)
{
  $('#output').append(reason);
}
function parseXML(xml)
{
$(xml).find("contact").each(function()
{
 $("#content").append($(this).find("CNT_NAME").text());
$("#content").append(": "+
$(this).find("CNT_ORGANIZATIONNAME").text() +" <br />");       
});      
}

<body> 

   <div id="title">
     <h3>Printing: Contact Name followed by organization</h3>
   </div>
       
   <div id="content">
       
   </div>

</body>

BUGS:

1) WORKS IN SAFARI/IE - DOES NOT WORK IN FIREFOX (ParseError - it doesn't even call the ParseXML function, just err)

2) Why so slow?? Why cca 10 seconds?

PLEASE HELP THX

ps.

would it be faster if i used NATIVE DOM METHODS? I really really like jQuery, it's so programmer friendly...

reply

Anonymous
03/12/2010 - 21:23

Any way to parse data from an xml file whose tags are not known before?

I mean is there any way to generalize it to parse any xml doc on the go?

reply

Add Comment

Put code snippets inside language tags:
[language] [/language]

Examples:
[javascript] [/javascript]
[actionscript] [/actionscript]
[csharp] [/csharp]

See here for supported languages.

Javascript must be enabled to submit anonymous comments - or you can login.

Sponsors