Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Processing XML with jQuery

Build dynamic, XML-based UI apps with jQuery, XML, DOM, and Ajax

Aleksandar Kolundzija (ak@subchild.com), Web developer, Meebo
Photo of Aleksander Kolundzija
Aleksandar Kolundzija is a web developer with over 10 years of industry experience, currently managing the Frontend Engineering team at Meebo. He is also the founder and creator of the Gallerama.com web-based photo management application. He holds a Computer Science degree from Hunter College. For more information on Alex, you can check out his blog at www.subchild.com or find him on Twitter by his handle @subchild.

Summary:  Did you know that you can use jQuery's fast and powerful DOM traversal and manipulation methods to process any XML file? This ability, combined with jQuery's ability to easily load XML files using Ajax, makes this JavaScript library a great choice for building dynamic, XML-based UI applications. In this tutorial, take a closer look at the specifics of this approach and explore its benefits and caveats. Along the way, you get an overview of DOM processing in the browser and discover how useful jQuery's methods can prove when you parse XML. The tutorial also outlines the basic steps in the development of a generic, browser-based live XML editor using the covered techniques.

Date:  01 Feb 2011
Level:  Intermediate PDF:  A4 and Letter (129 KB | 24 pages)Get Adobe® Reader®

Activity:  93248 views
Comments:  

jQuery and XML

Likely the main reasons for jQuery's huge popularity are its fast and simple traversal engine and its slick selector syntax. (Excellent documentation also really helps.) And although its primary use is HTML processing, in this section you explore how it works and how to apply it to processing XML files as well.

DOM manipulation and traversal with jQuery

To access any of jQuery's features you first need to make sure that the file jquery.js is included on the page. Having done that, you simply call jQuery() or the shorthand version $() and pass it a selector as the first argument. A selector is usually a string that specifies an element or a collection of elements if more than an element matches the given selector. Listing 20 shows some basic jQuery selectors.


Listing 20. Basic jQuery selectors

<script type="text/javascript">
     var allImages = $("img"); // all IMG elements 
     var allPhotos = $("img.photo"); // all IMG elements with class "photo"
     var curPhoto  = $("img#currentPhoto"); // IMG element with id "currentPhoto"
</script>

Keep in mind that the return value of the jQuery function always returns a jQuery object. This object is what allows the chaining of methods (see Listing 21), a feature it shares with a few other popular JavaScript frameworks (likely influenced by the Ruby programming language).


Listing 21. Basic jQuery operation with chained method calls

<script type="text/javascript">
     $("img").css({"padding":"1px", "border": "1px solid #333"})
.wrap("<div class='img-wrap'/>");
</script>

This code selects all images, sets padding and border on each of them, then wraps each in a DIV with class img-wrap. As you can tell, that's quite a bit of cross-browser functionality reduced to just a single line of code. For thorough information on jQuery selectors and methods, check out the excellent documentation on the jQuery website (see Resources).

Listing 22 shows how jQuery simplifies examples from the previous section.


Listing 22. Creating and injecting a DOM node with jQuery

<script type="text/javascript">
alert($("h1:first").html()); // .text() also works and might be better suited here

$("#auth").text("Sign Out");

var $li = $("<li>List Item Text</li>"); 
// $ is used as var prefix to indicate jQuery object
$("ul#nav").append($li);
</script>


Processing XML with jQuery

I mentioned that the first argument passed to the jQuery $() function is the string selector. The less common second argument allows you to set the context, or starting node for jQuery, to use as a root when making the selection. By default, jQuery uses the document element as the context, but optimizing code is possible by restricting the context to a more specific (and therefore smaller) subset of the document. To process XML, you want to set the context to the root XML document (see Listing 23).


Listing 23. Retrieving values from an XML document with jQuery

<script type="text/javascript">
     // get value of single node (with jQuery)
     var description = $("description", xmlData).text(); 
         // xmlData was defined in previous section

     // get values of nodes from a set (with jQuery)
var relatedItems = $("related_item", xmlData);
var relatedItemVals = [];
$.each(relatedItems, function(i, curItem){
     relatedItemVals.push(curItem.text());
});
</script>

That code cleans things up quite a bit. By passing the node name to the core jQuery $() function and setting the context, xmlData, you quickly get access to the node set you want. Getting the value of the node, though, is something that needs some exploration.

As the innerHTML property does not work for non-HTML documents, you cannot rely on jQuery's html() method to retrieve the contents of a node. jQuery also provides a method for cross-browser retrieval of the text of an HTML node. The text() method, as mentioned earlier, is a cross-browser wrapper for the innerText property, but even it behaves inconsistently across browsers when processing XML. Internet Explorer, for example, ignores what it considers the empty node values (spaces, tabs, breaks) as the contents of a node. This approach might seem more intuitive than Firefox's handling of the same, which interprets the related_nodes element from the sample XML file as a set of text nodes along with the related_items nodes. To get around this inconsistency, create custom methods for treating text nodes consistently. In doing so (see Listing 24) you make use of a few handy jQuery methods: contents(), filter() and trim().


Listing 24. Cross-browser JavaScript functions for accurate text value retrieval of a node

<script type="text/javascript">
/**
      * Retrieves non-empty text nodes which are children of passed XML node. 
      * Ignores child nodes and comments. Strings which contain only blank spaces
      * or only newline characters are ignored as well.
      * @param  node {Object} XML DOM object
      * @return jQuery collection of text nodes
      */
     function getTextNodes(node){
          return $(node).contents().filter(function(){ 
               return (
                    // text node, or CDATA node
                    ((this.nodeName=="#text" && this.nodeType=="3") 
|| this.nodeType=="4") && 
 // and not empty
                    ($.trim(this.nodeValue.replace("\n","")) !== "")
               ); 
          });
     }

     /**
      * Retrieves (text) node value
      * @param node {Object}
      * @return {String}
      */
     function getNodeValue(node){
          var textNodes = getTextNodes(node);
          var textValue = (node && isNodeComment(node)) ? 
                    // isNodeComment is defined above
node.nodeValue : (textNodes[0]) ?        $.trim(textNodes[0].textContent) : "";
          return textValue;
     }
</script>

Now look at how to set the node value (see Listing 25). Two things to keep in mind are that this operation is potentially destructive, as setting the text value of the root node overwrites all of its children. Also note that if a specific node has no prior text value, instead of setting it using node.textContent, set it with node["textContent"] because Internet Explorer doesn't like the first method (the property doesn't exist when blank).


Listing 25. Cross-browser JavaScript function for accurate setting of the text value of a node

<script type="text/javascript">
function setNodeValue(node, value){
          var textNodes = getTextNodes(node);
          if (textNodes.get(0)){
textNodes.get(0).nodeValue = value;
}
else {
node["textContent"] = value;
}
     }
</script>


DOM attributes and jQuery

Processing attributes of DOM elements is already pretty straightforward with plain old JavaScript as shown in examples from the previous section. As expected, jQuery provides simple equivalents for these, but furthermore, attributes can be used in selectors—a very powerful feature (see Listing 26).


Listing 26. Getting and setting DOM element attributes with jQuery

<script type="text/javascript">
     var item = $("item[content_id='1']", xmlData); 
// select item node with content_id attribute set to 1
     var pubDate = item.attr("date_published"); 
// get value of date_published attribute
     item.attr("archive", "true"); 
// set new attribute called archive, with value set to true
</script>

As you can see, jQuery's attr() method supports both the retrieval and setting of attributes. More importantly, jQuery provides excellent access to element retrieval by allowing attributes in selectors. In the example above, you selected the item with content_id attribute set to 1, from the xmlData context.


Loading XML through Ajax with jQuery

As you probably already know, Ajax is a web technology for asynchronous retrieval of XML (or text) from the server using JavaScript. Ajax itself relies on the XMLHttpRequest (XHR) API to send a request to and receive a response from the server. In addition to providing excellent DOM traversal and manipulation methods, jQuery also offers thorough, cross-browser Ajax support. That said, the loading of XML through Ajax is as native as Ajax gets, so you're on familiar ground. The way this works in jQuery is shown in Listing 27.


Listing 27. Loading an external XML file with jQuery's Ajax method

<script type="text/javascript">
$.ajax({
type     : "GET",
url      : "/path/to/data.xml",
dataType : "xml",
success  : function(xmlData){
var totalNodes = $('*',xmlData).length; // count XML nodes
alert("This XML file has " + totalNodes);
},
error    : function(){
     alert("Could not retrieve XML file.");
}
 });
</script>

The $.ajax() method has a number of additional options and can also be called indirectly through shortcut methods such as $.getScript(), which imports and executes a JavaScript file, $.getJSON(), which loads a JSON data file and makes it available to the success script, and so on. When requesting a file of type XML, though, you're stuck with the core $.ajax() method that has the advantage of forcing you to know only its syntax for any circumstance. In the example above, you simply request file /path/to/data.xml, specifying that the dataType is "xml" and that the request method is GET. After the browser receives a response from the server, it triggers either the success or the error callback function accordingly. In this example, a success callback alerts the total number of nodes. jQuery's star selector (*) matches all nodes. The key point is to note that the success callback function receives the data from the server as the first argument. The name of the variable is up to you, and as described earlier, that value becomes the context passed to any jQuery call intended to process the XML.

An important thing to keep in mind when processing Ajax in general is the cross-domain restriction, which prevents retrieval of files from different domains. The previously covered methods of server-side XML retrieval might be viable alternatives in your application.


Processing external XHTML as XML

Because XHTML is a subset of valid XML, there's no reason why you can't process it the same way you process XML. Why exactly you would want to is a separate topic, but the point is that you could. For instance, scrapping a (valid) XHTML page and extracting data from it is perfectly doable using this technique, even though I encourage a more robust approach.

While primarily intended for HTML DOM traversal and manipulation, jQuery can also be used for processing XML as well, though it requires the additional step of a getting the file to the browser. The topics covered in this section explain the different methods and provide the methods essential for processing the XML effectively.

4 of 9 | Previous | Next

Comments



static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=XML, Web development
ArticleID=620153
TutorialTitle=Processing XML with jQuery
publish-date=02012011
author1-email=ak@subchild.com
author1-email-cc=nancy_hannigan@us.ibm.com