jQuery .find() on a namespaced XML node fails on Google Chrome

Ran into a problem with…

Login

Blog History

Ran into a problem with a jQuery AJAX script that parses returned XML. It wouldn't work on Google Chrome when looking for a namespaced xml node using jQuery.find().

Apparently this (xml namespaces) can cause jQuery some minor heartburn but it's not a show stopper.

A namespaced nodename in XML has a name space prefix a colon then the node name. e.g.

<ns1:ld_part>65989

Basically namespace prefixes in XML stop collisions if two different coders want to refer to some thing with the same name

<!-- a clash -->
<item>us</item>
<item>them</item>

<!-- namespacing 
same same but different
-->

<ns1:item>us</ns1:item>
<ns2:item>them</ns2:item>

This Fails on Google Chrome:

// resp is XML passed from an ajax call to a server
success: function(resp){
	var jData = $( resp ); // jQueryise it
        var recordTop = jData.find("ns1\\:ld_det"); // search for the node
        // alert( recordTop.size()) returns 0 on Google Chrome

The following used to work on old versions (1.4.x) of JQuery however on jQuery v 1.9.1  this fails:

success: function(resp){
           var jData = $( resp );
           var recordTop = jData.find("[nodeName=ns1:ld_det]");

This jQuery forum post provided the answer http://forum.jquery.com/topic/jquery-namespaces-xml-parsing-12-1-2010

In the comments below there are several options of what to do

However I have been trying to parse a SOAP reply on IE8, 9 and Chrome and find('namespace\\:name') doesn't seem to work for me.

 

Option 1: Native jQuery 1.9.1 

As mentioned in the comment by "Erik T" below use a double element declaration

jData.find('ns1\\:ld_det, ld_det');

 

Option 2: Define a jQuery custom function and you can just use filterNode('ns1:result')

This could be expensive

/* add this to a file and call it after
* the standard jquery library
*/ 
$.fn.filterNode = function(name) {
      return this.find('*').filter(function() {
        return this.nodeName === name;
      });
    };

Call filterNode on the SOAP/XML returned from the Server


$.ajax({
	type : 'POST',
	processData : false, // must be false so jquery doesn't parameterize
	// the POST
	url : proxy_url,
	contentType : "text/xml",
	dataType : "xml",
	data : post_qdoc.xml(), // convert jquery xml object to xml string
	beforeSend : function(xhr) {
		xhr.setRequestHeader("SOAPAction", '""');
		xhr.setRequestHeader("SOAPTarget", post_url);
	},
	success : function(qdoc_response) {

		var response = $(qdoc_response).filterNode('ns1:result').text();
	},
	error : function(xhr, text_status, errorThrown) {

		global_error(text_status.toUpperCase() + ' : ' + errorThrown + ' : '
				+ 'Calling function = post_qdoc()');

	}
});

Tested Versions:

  • Google Chrome version 5.0.375.126 (Fedora 13)
  • jQuery JavaScript Library v1.4.2
  • jQuery 1.9.1 and IE 8, IE. 9, Google Chrome 26.0.1410.64,

 

 

7 Comments

  1. Soleil Golden

    You, sir, are my hero. I was struggling with this for hours! This solved my plug-in's main bug. I love you. 😀

    Reply
  2. admin

    LOL. Comment of the month!

    Glad it helped you Soleil.

    Reply
  3. John Smith

    Thanks a lot - it saved me hours!

    Reply
  4. johnsin

    Got a correction for you..
    You need to escape the namespace ":" properly with \. I have show the example below which works with the Itunes podcast XML feeds.

    item.description = jQuery(this).find("[nodeName=itunes\:summary]").eq(0).text();

    Reply
  5. Erik T

    None of the above works correctly on FF, IE and Chrome, here is the actual answer:

    jData.find("ns1\\:ld_det, ld_det");

    Reply
    • admin

      I wrote the original post for jquery 1.4.x and we are now at 1.9.x I think jQuery XML parsing support is a moving target.

      Reply
  6. Rik W.

    Thank you James and Erik!

    Your solution works with my code that parses XML from a SharePoint 2013 API, like this:

    ...
    $(xml).find('m\\:properties, properties').each(function ()
    {
    var myTitle = $(this).find('d\\:title, title').text();
    ...

    Tested ...

    ... on a PC running Microsoft Windows 7 SP1 Build 7601 and ...
    * Google Chrome 51.0.2704.103 m
    * Microsoft Internet Explorer 11.0.31
    * Mozilla Firefox 47.0
    * Opera 38.0.2220.31

    ... on a PC running Microsoft Windows 10.0 Build 10240 and ...
    * Google Chrome 51.0.2704.103 m
    * Microsoft Edge 20.10240.16384.0
    * Microsoft Internet Explorer 11.0.28
    * Mozilla Firefox 47.0
    * Opera 38.0.2220.31

    ... on an Apple iPad Mini 2 running iOS 9.3.2 and ...
    * Apple Safari
    * Google Chrome
    * Mozilla Firefox

    Which is nice.

    Reply

Submit a Comment

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

The reCAPTCHA verification period has expired. Please reload the page.