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

Written by James McDonald

August 16, 2010

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

Leave a Reply to Rik W. Cancel reply

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.

You May Also Like…

Squarespace Image Export

To gain continued access to your Squarespace website images after cancelling your subscription you have several...

MySQL 8.x GRANT ALL STATEMENT

-- CREATE CREATE USER 'tgnrestoreuser'@'localhost' IDENTIFIED BY 'AppleSauceLoveBird2024'; GRANT ALL PRIVILEGES ON...

Exetel Opt-Out of CGNAT

If your port forwards and inbound and/or outbound site-to-site VPN's have failed when switching to Exetel due to their...