XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.

advertisement

jQuery and XML
by Uche Ogbuji | Pages: 1, 2

Listing 4 (designers.css): CSS for listing 3 XML
* { display: inherit; }

 designers { display: block; }

 blurb {
   margin: 1em;
   width: 20em;
   display: block;
 }

 designer {
   display: inline;
   text-decoration: none;
   color: green;
   border: thin blue solid;
 }

 script { display: none; }

This is pretty straightforward CSS for XML, including the trick of changing the default display setting to inherit and the top level to block. This minimizes the huge, run-in block of text display effect. Notice also the rule for hiding the script elements. Listing 5 is the relevant bit for this article, designers.js.

Listing 5 (designers.js): JavaScript for listing 4 XML
$(function() {
     $('blurb').each(function() {
         $(this).find('designer').click(function() {
             //document.location.href = ... works in Mozilla but not  
 Safari
             window.location.href = $(this).attr('homepage')
         }); //close click(
     }); //close each(
 }); //close $(

 //append and html don't work for XML in FF2.  replace does

This short and sweet number just simulates basic linking behavior on all the designer elements. $('blurb').each (function() {}) selects all the blurb elements and then iterates over the lot. $(this).find('designer').click (function() {}) sets a mouse click event handler on each designer element, and the handler simply grabs the homepage attribute and redirects to that location.

I've learned that it can become quite unpredictable which jQuery API bits will work once you are handling XML directly in this way. For example, the append and replace methods don't seem to work on XML elements, thought the jQuery documentation provides no warning of this. The docs do warn that the html method doesn't work, but I expected that, anyway. But enough of jQuery does work in this scenario to get some useful work done.

Patching up XML Namespaces

jQuery has no selectors that understand XML namespaces. Even prior to version 1.2 when there was an option for XPath-like selectors, there was no namespaces support. This doesn't mean you can't use jQuery to process XML with namespaces. It just means you may have to sometimes take the escape hatch to DOM. Listing 6 is just the first relevant bits of listing 3 modified to use a default namespace.

Listing 6: XML in default namespace (excerpts)
 <?xml version='1.0' encoding='utf-8'?>
 <?xml-stylesheet type="text/css" href="designers.css"?>
 <designers xmlns='http://example.com/designers'>;
 ...
   <xhtml:script xmlns:xhtml="http://www.w3.org/1999/xhtml"
                 src="designers2.js"
                 type="application/javascript"/>
 </designers>

My first attempt at a script (designers2.js) that actually did a namespace-aware iteration over the {http://example.com/ designers}blurb (to use James Clark's notation of namespace names) is listing 7.

Listing 7: Using jQuery to select by XML namespace
NS = 'http://example.com/designers'

 $(function() {
     //Iterate over all elements with local name 'blurb'
     $('blurb').each(function() {
         //Check that the element truly is in the right namespace
         if ($(this).get(0).namespaceURI == NS) {
             $(this).find('designer').click(function() {
                 window.location.href = $(this).attr('homepage')
             }); //close click(
         }
     }); //close each(
 }); //close $(

Here within the primary iterator over the selected result, I use an if statement to further check the namespace URI of the matched DOM node. To get the DOM node itself I use the get method, which takes an index and gives you the DOM node with that index, in document order, from the selected results. Once I have the DOM node I can use DOM methods and properties such as namespaceURI. Listing 7 is not quite the jQuery way, though. After a while with the library you quickly get into the habit of simplifying things into the likes of listing 8, which is functionally equivalent to listing 7.

Listing 8: Using jQuery's filter method to select by XML namespace
NS = 'http://example.com/designers'

 $(function() {
     //Iterate over all elements with local name 'blurb'
     $('blurb').filter(function(index) {
         //Check that the element truly is in the right namespace
         return $(this).get(0).namespaceURI == NS;
     }).each(function() {
         $(this).find('designer').click(function() {
             window.location.href = $(this).attr('homepage')
         }); //close click(
     }); //close each(
 }); //close $(

The filter method takes an arbitrary function. Clearly this code is not as neat as operations that fit entirely into jQuery's world-view, but it gets the job done. If you do a lot of this sort of thing you might want to define a standalone function, say nsmatch which does the check, and can be passed to filter by name, reducing verbosity.

Wrap Up

JavaScript libraries are a matter of taste, and we can just thank our stars there is one for just about any taste. I came to enjoy jQuery because it made processing mainstream web content so much easier, and when I tried to make it do cool things with XML, I was pleased with how many things did just work, though some of the blind alleys were a bit unexpected. In this article I've given a quick overview of how you can use jQuery to process XML. I hope someone gets around to writing a plug-in that helps even more, providing the likes of namespace matching. jQuery is great work, and especially in the area of XMl processing, it can only get greater.



1 to 7 of 7
  1. does not work on latest jQuery
    2010-07-04 23:00:37 aaron.love.christ
  2. nice
    2010-06-29 12:35:18 fitrisartika
  3. Not Update when change xml file
    2009-02-12 00:08:08 hitec.vn
  4. Couldn't get the first example to work
    2008-10-22 06:58:03 vwiswell
  5. Namespace, prefix and jquery
    2008-09-11 12:10:40 SylvainH
  6. $(this).get(0)
    2007-10-16 11:39:24 aristotle
  7. Write an extension!
    2007-10-15 12:47:25 happygiraffe
1 to 7 of 7