jQuery Demo: Working With XML Documents

Posted November 27, 2007 at 7:05 AM by Ben Nadel

Tags: ColdFusion, Javascript / DHTML

As we learn about AJAX (Asynchronous Javascript and XML), our first thought is that it is very cool. Our second thought is usually that XML sucks and it's such a pain in the butt to work with. With that discovery, many of us turn to using AJAX purely as a text/HTML delivery system or we switch to using JSON (Javascript Object Notation) which is infinitely easier to work with on the client. And, while I tend to go with JSON for my AJAX functionality, let's not forget that XML is a very cool delivery format.

If you have to use XML, you might want to consider using jQuery as well. It's very rare that you see any examples of jQuery being used with XML, but the fact is, all the features that make jQuery so amazing for XHTML traversal and searching also hold true for XML documents. The jQuery factory method ($) can take, as one of it many data types, an XML document object model. Once you do this, you can pretty much use the resultant jQuery stack as if it were an XHTML document object model (which should make you much more comfortable).

To demonstrate this, let's set up a rather simple ColdFusion page that just returns some XML data to an AJAX request:

  • <!--- Build the XML into a ColdFusion XML document. --->
  • <cfxml variable="xmlGirl">
  •  
  • <person type="girl">
  •  
  • <head>
  • <eyes value="brown" />
  • <hair value="brown" />
  • </head>
  •  
  • <torso>
  • <bust value="34A" />
  • <navel value="pierced" />
  • </torso>
  •  
  • <legs>
  • <waist value="24" />
  • <hips value="36" />
  • <calves value="22" />
  • </legs>
  •  
  • </person>
  •  
  • </cfxml>
  •  
  •  
  • <!--- Convert XML to a string. --->
  • <cfset strGirlXml = Trim( ToString( xmlGirl ) ) />
  •  
  •  
  • <!---
  • Set the length of the content. This will help the browser
  • know when the request is completel.
  • --->
  • <cfheader
  • name="content-length"
  • value="#Len( strGirlXml )#"
  • />
  •  
  • <!---
  • Set the XML document type. This will help the AJAX calling
  • program to determine which type of data is being returned
  • (XML, JSON, Script, etc).
  • --->
  • <cfcontent
  • type="text/xml"
  • variable="#ToBinary( ToBase64( strGirlXml ))#"
  • />

Notice that we are building the XML document using ColdFusion CFXml tags. We could have easily done this same task using ColdFusion's CFSaveContent tag for buffered output, but I think there is something nice about using CFXml to ensure that only proper XML structures are created. This ColdFusion XML document is then converted to a string and streamed back to the client.

Ok, now that we have our XML feed set up (girl.xml.cfm), let's create the HTML page that will consume this data:

  • <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  • <html>
  • <head>
  • <title>jQuery Demo: Using jQuery With XML</title>
  •  
  • <!-- Linked files. -->
  • <script type="text/javascript" src="jquery-latest.pack.js"></script>
  • <script type="text/javascript">
  •  
  • // This function will handle the xml Onload event
  • // handler. It will be passed the XML data object
  • // and the status of the XmlHttpRequest object.
  • function XmlOnLoad( xmlData, strStatus ){
  • // Let's start out by converting the XML data
  • // returned by the AJAX request into a jQuery
  • // XML document object model.
  • var jData = $( xmlData );
  •  
  • // Get the person object (but only if it is a girl).
  • var jGirl = jData.find( "person[ type = 'girl' ]");
  •  
  • // Get the direct children of the girl. These
  • // will represent the sections of the body.
  • var jSections = jGirl.children();
  •  
  • // For each of the section, we want to create
  • // an element in the girl definition list. Get a
  • // pointer to said definition list.
  • var jList = $( "#girl" );
  •  
  •  
  • // For each section, create a list item.
  • jSections.each(
  • function( intSectionIndex ){
  • var jSection = $( this );
  • var jTerm = $( "<dt></dt>" );
  •  
  • // Set the term text.
  • jTerm.text( jSection[ 0 ].nodeName );
  •  
  • // Append term to list.
  • jList.append( jTerm );
  •  
  •  
  • // Now, for each part of the section, we are
  • // going to need to create a list.
  • jSection.children().each(
  • function( intPartIndex ){
  • var jPart = $( this );
  • var jDef = $( "<dd></dd>" );
  •  
  • // Set the DD text.
  • jDef.text(
  • " - " +
  • jPart[ 0 ].nodeName + ": " +
  • jPart.attr( "value" )
  • );
  •  
  • // Append to list.
  • jList.append( jDef );
  • }
  • );
  • }
  • );
  • }
  •  
  •  
  • // When the document has loaded, request the girl
  • // XML object which will then use to populate the
  • // XHTML document.
  • $(
  • function(){
  • $.get(
  • "girl.xml.cfm",
  • {},
  • XmlOnLoad
  • );
  • }
  • );
  •  
  • </script>
  • </head>
  • <body>
  •  
  • <h1>
  • jQuery Demo: Using jQuery With XML
  • </h1>
  •  
  • <dl id="girl"></dl>
  •  
  • </body>
  • </html>

This code looks complicated because there are a lot of comments, but really, it's quite simple. The magic here is that in my AJAX callback method, I am taking the returned XML document and creating a jQuery stack object:

  • var jData = $( xmlData );

jData, our jQuery instance object, now contains the XML document object model (#document) which can be traversed using any of jQuery's sweet ass functions (ex. find(), children(), parent(), etc.).

The code of our page takes the XML document, which defined body parts, and uses the data to populate a Definition List. Running the above code, we get:

jQuery Demo: Using jQuery With XML

head
- eyes: brown
- hair: brown
torso
- bust: 34A
- navel: pierced
legs
- waist: 24
- hips: 36
- calves: 22

So, while raw XML can be complicated to work with, using XML in conjunction with jQuery can make things much easier. I am not advocating using this over JSON, as I think JSON is the bee's knees; but certainly, in a scenario where XML is your only option (as it might be with something like centralized input validation), jQuery is certainly something you're gonna want to check out.




Reader Comments

Nov 27, 2007 at 1:38 PM // reply »
2 Comments

Thanks for the excellent article! I was trying to work out how to use jQuery with XML a few weeks back and this article clears things up perfectly! :D


Nov 27, 2007 at 1:51 PM // reply »
11,238 Comments

@Guy,

Glad to help. Yeah, you really don't see many examples with this. Most of the time, just a footnote about "This also works with XML". So, I figured I would put this out there.


Nov 30, 2007 at 7:14 AM // reply »
31 Comments

Hi Ben,

Good article. I haven't looked into JQuery yet (only CF8 Ajax functions and Spry) but it's something I do want to experiment with and this will help.

I do have a question though. Why are you converting the XML to base64 and then to binary - I couldn't figure out why that was necessary.


Nov 30, 2007 at 12:05 PM // reply »
11,238 Comments

@James,

I do that because I find using the CFContent tag to set the type of data and stream the data quite convenient. By streaming a binary variable, the CFContent takes care of all the white space management. With an XML file, you have to be careful not to return leading white space (or at least it is best practice). By streaming the variable, you know for sure that none of the pre-page processing will cause the XML data to be malformed.


bay
May 23, 2009 at 4:32 AM // reply »
1 Comments

great article!
here's a quick question..
I'm very VERY new to all this...
so I'm rack my brain trying to get how ajax and jquery all work.
say if I have three buttons...each with ID 1, 2, and 3.
I have an xml file with 3 different pieces of info each with an id of 1, 2, and 3 as well. How would I make a string that takes the id of the button...matches it to the ID of the xml...then spits out the corresponding info?


Jul 16, 2009 at 8:39 PM // reply »
2 Comments

Hey Ben, you saved my life. I needed to build a 3-select menu decision tree with data driven by an XML file. I thought I couldn't be able to do it using jquery, because I was googling xpath and jquery and reading a lot about how jquery not supporting xpath but this will work. Thanks.


Jul 18, 2009 at 1:28 PM // reply »
11,238 Comments

@Nick,

Glad to help. If you get stuck, drop us a line.


Oct 5, 2009 at 5:27 AM // reply »
1 Comments

Hi all,
When i try to parse an xml which is in string using jquery, it doesnt work with ie whereas it perfectly works in mozilla and other browsers. Can any body help me in this issue thanks in advance.

-Srini


Oct 16, 2009 at 7:13 AM // reply »
5 Comments

Hi Srini

I had the same issue when I started out using this blog post from Ben - but then I got to know about this: http://dev.jquery.com/ticket/3143

Its an issue with IE in the sense that it does not recognise a string as XML when passed through the jQuery Constructor and hence will never traverse it; but in FF, the same code would work fine.

The fix for this is also given in the link I provided above.

Cheers
Sreenath


Oct 16, 2009 at 7:55 AM // reply »
11,238 Comments

@Srinivasan, @Sreenath,

Yeah, IE has some issues parsing XML that we input manually. That link provided above by @Sreenath looks good. Rest assured, though, that IE can handle XML that comes back via AJAX (as far as I know).


Dec 21, 2009 at 11:03 PM // reply »
1 Comments

Thank you for this. I'm grabbing external domain XML with PHP and passing it to JQuery as a JSON object and was going crazy trying to get it to work. The solution in the link fixed it right up!


Dec 22, 2009 at 8:21 AM // reply »
11,238 Comments

@Miles,

Glad you got it working.


Jun 16, 2010 at 12:40 PM // reply »
1 Comments

How may I use jQuery to select processing instruction node in xml? Essentially I would like to get the value of the "href" in the "xml-stylesheet" processing instruction

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="cdcatalog.xsl"?>


Dec 21, 2010 at 5:17 AM // reply »
2 Comments

Hey thanks Ben..

That was a great one.
I am a starter to jQuery

Now, I created tags in xml that resemble the controls of html eg,
<Controls>
<input id="txtName" type="text" value="" maxlength="20"></input>
</Controls>

I successfully converted this to a html control using javascript.

But I want to do the same using jQuery. How would I be able to do it ??
Please advise.


Jan 5, 2011 at 2:14 AM // reply »
2 Comments

Hi Ben !

Nice article! I'm having some issue with CDATA when parsing, read lot about it but cant figure out the correct way to do it (cross-browser). So if u know a work aorund it would be great !

thanks!

nico!


Jan 6, 2011 at 9:47 AM // reply »
11,238 Comments

@Rahesh,

It might be easier to send the response back as JSON and have the "controls" key contain the HTML for the controls, rather than an XML representation of the controls. That way, you can just dump the HTML into the DOM and it should work right out of the box.

@Nico,

Hmm, I have not done too much with CDATA. For AJAX, I mostly use JSON for all of my data transfer these days (including HTML markup). It makes this much more simple in my opinion. Sorry I don't have better advice on this matter.


Jan 6, 2011 at 2:25 PM // reply »
2 Comments

@Ben, thanks anyway brother!

greats from Argentina !

nico!


Feb 28, 2011 at 12:31 AM // reply »
2 Comments

@rajesh,

hey thanks for the help...

really appreciated. :)


Mar 24, 2011 at 8:31 AM // reply »
1 Comments

hi,

im tryin to edit an xml file on my web server through jquery, is there any way i can do that?


Mar 24, 2011 at 8:50 PM // reply »
11,238 Comments

@Mohammed,

You'd have to post the XML back to the server and use a server-side scripting language (like ColdFusion) to save the XML back to the remote file system. There's nothing in jQuery specifically to help you do that.


Rus
Mar 29, 2011 at 9:32 AM // reply »
1 Comments

Great article! Helped me out with the basics of handling xml in jQuery.

btw, this page is a top google result for "jquery xml navigation" keyword, despite the lack of the word "navigation" on this page, I guess your "screen readers" accessibility added an extra value for SEO.


Apr 15, 2011 at 7:01 AM // reply »
1 Comments

Excellent article very useful.

I have a scenario where I get the XML from the server convert it to a Jquery object by
$xmlDoc= $(XMLFromServer);

Now I want to convert Jquery Object to XML and send it back to the server.

Any help much appreciated

Thanks
Suhu


Jul 27, 2011 at 11:13 AM // reply »
1 Comments

you can take a look this solution,i think this is good solution:
http://haha808.com/?p=2292


Sep 15, 2011 at 9:08 AM // reply »
2 Comments

Hi..
Thanks for sharing this information and resources it's really help full for me with the help of this we can improve our designs and development I really inspire with this information thanks


Sep 27, 2011 at 2:56 PM // reply »
1 Comments

Thanks Ben for sharing this,

I am now able to get cross site RSS feed using JQuery, CF and FuseBox

Information on this blog is useful as always.


:/
Oct 25, 2011 at 11:03 AM // reply »
1 Comments

Kinda creepy example code, yeah?


Jul 10, 2012 at 8:23 AM // reply »
1 Comments

Hello Ben,

I reached your blog searching for the solution for my problem, but couldn't understand how to sort out that.

Can you please check this link - http://stackoverflow.com/questions/11412777/slider-image-fetching-through-xml-in-coldfusion

May be you can help a bit to save me.

Thanks,
RajeevK



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 20, 2013 at 11:45 AM
Using jQuery's Animate() Step Callback Function To Create Custom Animations
This is really useful. I found out that you don't actually have to use a dummy css property (surprisingly). To animate a property in a linear-gradient for instance I did this this.css('someLinearGra ... read »
May 20, 2013 at 10:51 AM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Josh, Oh snap! You're totally right! I'm not sure I've ever tried that. I did know that you can call a number of other array-methods on ColdFusion query columns: http://www.bennadel.com/blog/167 ... read »
May 20, 2013 at 10:45 AM
Using A Dynamic Column Name With ValueList() In ColdFusion
@Ben - I believe you can achieve the same functionality with ColdFusion's built in ArrayToList() function. ArrayToList( users[ "id" ] ); ... read »
May 20, 2013 at 10:21 AM
My Experience With AngularJS - The Super-heroic JavaScript MVW Framework
Is there any error logging and handling framework in angularjs, if not then in what way I can do this. ... read »
May 19, 2013 at 2:31 PM
My Experience With AngularJS - The Super-heroic JavaScript MVW Framework
It's funny really just how well that image describes the way I would imagine most people that go with angular for some project is. I have had a similar roller-coaster ride with it as well, but not qu ... read »
May 17, 2013 at 7:42 PM
HashKeyCopier - An AngularJS Utility Class For Merging Cached And Live Data
Ben - thanks so much for posting these Angular articles and findings, they've been a huge help towards learning one of the more 'complex' JavaScript frameworks out there (IMO). I have been using Angu ... read »
May 16, 2013 at 5:01 PM
UPDATE: Parsing CSV Data Files In ColdFusion With csvToArray()
Your code was the closest thing I've found to obtaining some direction for converting ISO fields to values that CF can translate properly. Thank you for posting! ... read »
May 15, 2013 at 6:07 PM
Making SOAP Web Service Requests With ColdFusion And CFHTTP
Ben, you once again saved my bacon at work. Thank you, thank you, thank you! ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools