Video Presentation: Manipulating XML With jQuery

Posted July 10, 2009 at 10:24 AM by Ben Nadel

Tags: Javascript / DHTML

NOTE: Right now, the following examples only work in Mozilla-based browsers (meaning, not in IE). I am working on an update that is IE-compatible.

We all know that jQuery is the most awesome Javascript library around. Every day, we are using jQuery to create richer, more dynamic, more effective user experiences on the web and in our AIR applications. Hands down, it's the fastest, most effective way to create Javascript-based user interfaces. But, jQuery is also quite good at reading and manipulating XML documents. Since XHTML is really just a subset of XML, it should be no surprise that just about everything we can do with XHTML documents, we can also do with XML documents by way of jQuery.

In the following mini video presentation, I demonstrate how to use jQuery to do all of the following:

  • Create XML documents from scratch.
  • Add new sub-trees to an XML document object model.
  • Perform contextual searches on the XML DOM.
  • Access, update, and create XML attributes.
  • Trim sub-trees from an XML document object model.
  • Even bind and trigger custom events on an XML tree.

In short, the video demonstrates that all of the actions you like to perform on XHTML, can also be performed on XML.

 
 
 
 
 
 
 
 
 
 

If you want to play around with this code yourself, here is the HTML page that I demonstrated in the video:

  • <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  • <html>
  • <head>
  • <title>Manipulating XML With jQuery</title>
  • <script type="text/javascript" src="jquery-1.3.2.js"></script>
  • <script type="text/javascript">
  •  
  • // When the DOM is ready, run the scripts.
  • $(function(){
  • // Build the base data XML object. We are building the
  • // XML collection in this cause, but this could have
  • // just as easily come from an AJAX call of type XML.
  • var jData = $( "<data></data>" );
  •  
  • // Output the info to the output.
  • output( "Data Size: " + jData.size() );
  •  
  •  
  • // ----------------------------------------------- //
  •  
  •  
  • // Append a dataum node to the XML collection.
  • jData.append(
  • "<datum id='1'>\
  • <name>Tricia</name>\
  • <hair>Brunette</hair>\
  • </datum>\n\
  • <datum id='2'>\
  • <name>Joanna</name>\
  • <hair>Brunette</hair>\
  • </datum>\n\
  • <datum id='3'>\
  • <name>Eva</name>\
  • <hair>Blonde</hair>\
  • </datum>"
  • );
  •  
  • // Query for all the datum nodes.
  • var jDatum = jData.find( "datum" );
  •  
  • // Output the size of the collection and the
  • // HTML (XML) of the data node.
  • output(
  • ("Datum Size: " + jDatum.size()),
  • jData.html()
  • );
  •  
  •  
  • // ----------------------------------------------- //
  •  
  •  
  • // Find Tricia's node. She is the datum record with
  • // the id of 1.
  • var jTricia = jDatum.filter( "[ id = 1 ]" );
  •  
  • // Output tricia's node.
  • output(
  • "Tricia's Node",
  • ("ID: " + jTricia.attr( "id" )),
  • jTricia.html()
  • );
  •  
  •  
  • // ----------------------------------------------- //
  •  
  •  
  • // Find the blond girl in the node set.
  • var jBlonde = jData.find(
  • "datum:has(hair:contains('Blonde'))"
  • );
  •  
  • // Output the blonde node.
  • output(
  • "Blonde's Node",
  • ("ID: " + jBlonde.attr( "id" )),
  • jBlonde.html()
  • );
  •  
  •  
  • // ----------------------------------------------- //
  •  
  •  
  • // Blondes might have more fun, but not in my
  • // programming world. Remove the blonde node from
  • // its parent data set (the data node).
  • jBlonde.remove();
  •  
  • // Output the data node to see if blondie was
  • // removed from the party.
  • output(
  • "Data (without Blondie):",
  • jData.html()
  • );
  •  
  •  
  • // ----------------------------------------------- //
  •  
  •  
  • // Let's rate the hottness of the remaining girls.
  • // To start with, let's add a default attribute with
  • // not value.
  • jDatum.attr( "hotness", "unknown" );
  •  
  • // Output the updated data set.
  • output(
  • "Data (with hotness attributes):",
  • jData.html()
  • );
  •  
  •  
  • // ----------------------------------------------- //
  •  
  •  
  • // Tricia is a total babe. If she were a children's
  • // cereal, she'd be magically babelicious. As such,
  • // let's take her existing node reference and update
  • // the hotness attribute.
  • jTricia.attr( "hotness", 10 );
  •  
  • // Output the updated data set.
  • output(
  • "Data (with Tricia update):",
  • jData.html()
  • );
  •  
  •  
  • // ----------------------------------------------- //
  •  
  •  
  • // Even though we are dealing with an XML document
  • // that is not rendered on the page, we can still
  • // bind and trigger events on it.
  • jData.bind(
  • "hug",
  • function( objEvent ){
  • // Get the target node for the event.
  • var jTarget = $( objEvent.target );
  •  
  • // Check to see if the target node of the hug
  • // event was a datum node (we don't care if
  • // another node triggered this event).
  • if (jTarget.is( "datum" )){
  •  
  • // Output that the given girl node was
  • // hugged (you sly dog you!).
  • output(
  • "Datum Node Hugged:",
  • jTarget.html()
  • );
  •  
  • }
  • }
  • );
  •  
  • // Trigger a hug event on Tricia.
  • jTricia.trigger( "hug" );
  •  
  •  
  • // ----------------------------------------------- //
  •  
  •  
  • // We are done. Let's empty the data set.
  • jData.empty();
  •  
  • // At this point, we have completely disconnected the
  • // Datum collection from the Data container. As such,
  • // we shouldn't be able to access the parent node of
  • // any of the datum nodes. To test this, try to grab
  • // Tricia's parent.
  • var jParent = jTricia.parent();
  •  
  • // Output the parent collection size and the size of
  • // data child collection.
  • output(
  • ("Parent Size: " + jParent.size()),
  • ("Data Child Size: " + jData.children().size())
  • );
  •  
  • });
  •  
  •  
  • // I output my arguments to the output, each on a new line
  • // followed by an extra line break.
  • function output(){
  • var jOutput = $( "#output" );
  •  
  • // Loop over arguments and output them.
  • $.each(
  • arguments,
  • function( index, value ){
  • // Clean the value.
  • value = $.trim( value );
  •  
  • // Remove tabs for demo.
  • value = value.replace(
  • new RegExp( "\\t+", "g" ),
  • " "
  • );
  •  
  • // Remove all leading spaces.
  • value = value.replace(
  • new RegExp( "^\\s+", "gm" ),
  • ""
  • );
  •  
  • // Append to existing content.
  • jOutput.val( jOutput.val() + value + "\n" );
  • }
  • );
  •  
  • // Output an additional line break.
  • jOutput.val(
  • jOutput.val() +
  • "\n-------------------------\n\n"
  • );
  • }
  •  
  • </script>
  • </head>
  • <body>
  •  
  • <h1>
  • Manipulating XML With jQuery
  • </h1>
  •  
  • <form>
  •  
  • <textarea
  • id="output"
  • style="width: 100% ; height: 400px ; font-size: 16px ;"
  • ></textarea>
  •  
  • </form>
  •  
  • </body>
  • </html>

If you still haven't looked into jQuery, do so immediately. If you'd like to get a great primer on the subject, take a look at my presentation: An Intensive Exploration of jQuery. It is one of the best Javascript libraries out there; and, as stated before, I'll never start another web development project without it.




Reader Comments

Jul 10, 2009 at 7:37 PM // reply »
11,238 Comments

This is really embarassing, but this code does NOT work in Internet Explorer. I will debug this and post an update.


Jul 10, 2009 at 7:38 PM // reply »
4 Comments

Hi Ben,

I would like to express my sincere thanks for this fantastic video. I must say again as I said on my previous email - I think that your videos are head and shoulders above the rest.

Very clearly worded, and more specifically, extremely well exemplified.

Also, thanks for passing on extensive knowledge and support. I have really enjoyed watching the video and am very grateful for the opportunity to ask further questions.

Below I have some questions and also discuss the problems/bugs I encountered while trying the code:

1 - In IE6, the code does not run properly. I have debugged the code and this is the extract of code from the JQUERY library where it breaks:

Does the JQUERY library offers cross browser support including IE6?

2 - I have my own little javascript library which I use to work with xml. I use XPATH quite extensively to find the nodes I need in the xml. I use XPATH expression like this:

Is it possible to use XPATH with JQUERY?

3 - There is something that is still not clear to me. How do I move/copy an specific XML structure from one XML into another XML in a specific location ?

Suppose I have this xml:

XML1

Suppose I want to move/copy all the address elements from XML1 with all its attributes and child elements to another xml - XML2 under the addresses tag. I am not sure how to achieve this!!!

XML2

This would be the required output:

I would appreciate if you could show us some code examples.

Again thanks for your help.

Cheers

C


Jul 10, 2009 at 7:41 PM // reply »
4 Comments

I am sorry, but I was not able to post the xml and code sample since the blog was blocking my message.


Jul 10, 2009 at 7:43 PM // reply »
11,238 Comments

@Cleyton,

Don't worry about it. My blog blocks things that it thinks might be spammers (based on content). You probably just a link tag or something.

I got your email. Thanks for pointing out this *glaring* IE compatibility issue. I apologize for not testing this. I just assumed...


Jul 10, 2009 at 8:46 PM // reply »
1 Comments

Hi Ben.
Excelent video.
Thanks for share the knowlege.


Jul 11, 2009 at 6:27 AM // reply »
1 Comments

Nice video, what programs are you using to produce these?


Jul 12, 2009 at 2:02 PM // reply »
4 Comments

Hi Ben,

I was wondering if the reason why the code does not work in IE6/7 is because in IE6/7 the way to create an xml document is different from Mozilla-based browsers.

IE uses Activex
new ActiveXObject("MSXML2.DOMDocument")//("MSXML2.DOMDocument.4.0")

FF uses

parser.parseFromString(nd, "text/xml")

of

document.implementation.createDocument

Hope this will shed some light.

One thing I don't understand about the JQuery library is how it treats an xml string you pass to it. Does it create an xml document?

Also, shouldn't the library be cross browser so that it would in IE6 as well?

Cheer

C


Jul 13, 2009 at 2:32 PM // reply »
1 Comments

Hi Ben,

Great work and thanks for sharing the info too. Once you've managed to spend some time getting it to work with IE, please post back here so that we can all take a look?

Thanks again,
David


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

@Andy,

I've been using JING to make most of these.


Jul 30, 2009 at 12:37 PM // reply »
4 Comments

Hi Ben,

We have been waiting for a reply from you regardin the sample examples working only in Mozilla-based browsers (meaning, not in IE).

You said you were working on an update that woudl be IE-compatible.

Could you please shed some light on the outcome of your tests?

I have noticed that a lot of people are having the same problem i.e. to get JQuery to manipulate xml in IE and also in FF 3.0.

Based on my research I believe there is a bug in JQuery when it comes to working with XML.

What are your thoughts on that?

Cheers

C


Aug 5, 2009 at 10:07 AM // reply »
11,238 Comments

@Cleyton,

Sorry my man, I have been so busy with exploring the ColdFusion 9 alpha that I've hardly had any free time. I have a conference coming up next week, so I will most likely have more free time after that. Sorry for the suspense!


Sep 8, 2009 at 10:13 AM // reply »
2 Comments

Hi Ben, first of all thanks for this great video.

I've a problem using it when the JQuery XML comes from an Ajax call.
Even if I specify the XML dataType I get an error when I try to get the .html() of the document or of a single node.

Do you know if this is a JQuery bug or if I miss something?

Thanks


Sep 8, 2009 at 12:44 PM // reply »
11,238 Comments

@Stefano,

This might be the FireFox / IE discrepancy. I only tested this in FireFox and then realized that it doesn't quite work the same way in IE.

I have been meaning to find time to fix it up, but have been under a lot of deadlines. September should be more quiet and I'll see if I can get to the bottom of some of this.


Sep 9, 2009 at 4:41 AM // reply »
2 Comments

Hi Ben, sorry I forgot to say I'm using Firefox with JQuery 1.3.2

I've an .ajax call directly to an XML file with datatype specified as XML.
With the result I've no problem doing everything in your video but I can't access the .html() method.

I get an error on jquery file row 486: this[0].innerHTML is undefined.

This is not a big problem for me, cause I don't really need to get the .html() or I can get it using a different approach cause I'm developing only on firefox, but it seems really a strange behaviour.


Sep 12, 2009 at 10:49 PM // reply »
11,238 Comments

@Stefano,

Very interesting. I wonder if is has to do with the fact that I am manually building the XML data string locally, rather than getting it from a remote URL? Very curious.


Oct 8, 2009 at 5:53 PM // reply »
1 Comments

Ben -

First off, thanks for posting your work with jQuery - it's a big help!

I am trying to get this working in IE6 as well, and it appears that if I use a dataType of 'text', all works fine (in Safari) but not in IE6. When I switch the dataType to 'xml', as already mentioned in an earlier post, the html() property no longer works (in Safari or IE6). By using text() instead of html(), I can get the text, but not the XML elements themselves. Argh! Still looking, but so far I see no (browser-independent) way of serializing the xml object to it's string representation...anyone else having any luck???


Oct 8, 2009 at 7:03 PM // reply »
1 Comments

1.) there is not html() function for an xml node, because xml elements do not have a innerHTML property which is what the html() function utilizes. In fact by my understanding og JQ, using html on a pure xml doc shouldnt work at all unless the xml node in question happens to have the XHTML or HTML namespace attached to it. This means if you want to get the nodes as a sertialized string you need to create an extension or global utilitiy function to do so, for example:

<code>
$.fn.xmlString = function(){
var str = '';
this.each(function(){
if(window.ActiveXObject){
str += this.xml;
} else {
str += (new XMLSerializer()).serializeToString(this);
}
});

return str;
};
</code>

2.) I could be wrong about this because i just ran across the issue (in fact i found this post in trying to find proof that my suspicion is correct), but you cant simply move a node from document a to document b because they dont have the same owner document - at least this is the way it is in php when you using DOMDocument and/or SimpleXml. There are particular function you use for this... I think this is probably an issue with differences between the underlying implementation of XML in the browsers - oddly enough this implys Mozilla/Gecko is actually LESS strict than MS and Webkit. What really gets me is that i beleive both Webkit and Gecko use nearly identical if not the same XML DOM implementations (as implied by the simple if/else statement in the searializer above.

Hope that helps.


Apr 1, 2010 at 3:01 AM // reply »
1 Comments

Can we convert xml file into a csv file using this jQuery?If yes,can u please provide me the code.


Apr 7, 2010 at 10:05 PM // reply »
11,238 Comments

@Pavan,

Are you talking about simply creating a comma-delimited list? Or creating an actual physical file?


Amy
Apr 9, 2010 at 11:53 AM // reply »
1 Comments

Thank You


Apr 10, 2010 at 2:26 PM // reply »
1 Comments

Here is a simple test I put together to get around the IE problem.

if ($.browser.msie)
{
var xDom = new ActiveXObject("Microsoft.XMLDOM");
jData = xDom.loadXML("<data></data>");
}
else
{
jData = $("<data></data>");
}
alert(jData.size());


Apr 19, 2010 at 10:17 PM // reply »
11,238 Comments

@John,

Cool tip - I'll have to give it a try. Thanks.


Aug 20, 2010 at 4:15 AM // reply »
1 Comments

This was really useful. I've been doing the same thing lately. But, I just can't get it to work in IE8... Anyone have succeeded in this?


Aug 21, 2010 at 3:05 PM // reply »
11,238 Comments

@Eirik,

My code won't work in IE, unfortunately. But, if I recall correctly, there's a number of comments above in which people have outlined how to get this to work in IE-based browsers. I believe you need to parse the XML a bit differently (using a proprietary IE technology).


Aug 28, 2010 at 3:43 PM // reply »
1 Comments

Hi,

IE8 uses the standard DOM class that is used by other browsers like FF.

In your code you could try to check if it is IE8 and then use the standard way to create an xml document.

Please let us know if this works.

Cheer

C


Apr 23, 2011 at 8:09 PM // reply »
1 Comments

Binding events and manipulating shared subtrees with multi-part selectors is all well and good, but how do I get Tricia's phone number?


bbb
Nov 11, 2011 at 4:40 AM // reply »
1 Comments

Binding events and manipulating shared subtrees with multi-part selectors is all well and good, but how do I get Tricia's phone number?

@Ben,


bb
Nov 11, 2011 at 4:41 AM // reply »
1 Comments

@Ben,

This might be the FireFox / IE discrepancy. I only tested this in FireFox and then realized that it doesn't quite work the same way in IE.

I have been meaning to find time to fix it up, but have been under a lot of deadlines. September should be more quiet and I'll see if I can get to the bottom of some of this.


Sep 5, 2012 at 4:27 AM // reply »
1 Comments

Thanks for a great walk trough of how to use jQuery combined with XML. Really makes my mind bubbling with ideas.



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 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 10:37 PM
Very Simple Pusher And ColdFusion Powered Chat
hi id making plz easy ... 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 »
May 15, 2013 at 4:15 PM
What If All User Interface (UI) Data Came In Reports?
@Josh, Thanks! @Ben, I definitely recommend the David West book "Object Thinking" I've been quoting from. It goes deeply into the philosophy and history of OO programming. His breadth ... read »
May 15, 2013 at 11:36 AM
Ask Ben: Print Part Of A Web Page With jQuery
I found this helpfull when you need to keep (refresh) the original parent page after closing the iframe child print dialog (Hoping you're not using a form at this time so it won't submit again): On ... read »
May 14, 2013 at 7:13 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, If there's any books you'd recommend on the subject of domain modelling, I'd love to hear it. I just downloaded the free PDF of "Domain Driven Design Quickly". Figured I'd give it ... read »
May 14, 2013 at 6:57 PM
The UX Of Prototyping: Low-Fidelity Is The New High-Fidelity
@Phillip, I'm not sure I follow what you mean? Are you saying that you looked at the list of widgets provided by the jQuery UI and let that be your style guide? ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools