JQuery parsing XML with namespaces

I am new to jQuery and would like to parse an XML document.

I can parse plain XML with default namespaces, but with xml, for example:

<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema"> <s:Schema id="RowsetSchema"> <s:ElementType name="row" content="eltOnly" rs:CommandTimeout="30"> <s:AttributeType name="ows_ID" rs:name="ID" rs:number="1"> <s:datatype dt:type="i4" dt:maxLength="4" /> </s:AttributeType> <s:AttributeType name="ows_DocIcon" rs:name="Type" rs:number="2"> <s:datatype dt:type="string" dt:maxLength="512" /> </s:AttributeType> <s:AttributeType name="ows_LinkTitle" rs:name="Title" rs:number="3"> <s:datatype dt:type="string" dt:maxLength="512" /> </s:AttributeType> <s:AttributeType name="ows_ServiceCategory" rs:name="Service Category" rs:number="4"> <s:datatype dt:type="string" dt:maxLength="512" /> </s:AttributeType> </s:ElementType> </s:Schema> <rs:data> <z:row ows_ID="2" ows_LinkTitle="Sample Data 1" /> <z:row ows_ID="3" ows_LinkTitle="Sample Data 2" /> <z:row ows_ID="4" ows_LinkTitle="Sample Data 3" /> </rs:data> </xml> 

All I really need is <z:row> .

So far I have been doing:

 $.get(xmlPath, {}, function(xml) { $("rs:data", xml).find("z:row").each(function(i) { alert("found zrow"); }); }, "xml"); 

Not really lucky. Any ideas? Thank.

+78
javascript jquery xml namespaces xsd
May 12 '09 at 16:46
source share
20 answers

I understood.

It turns out that \\ is required to execute a colon.

 $.get(xmlPath, {}, function(xml) { $("rs\\:data", xml).find("z\\:row").each(function(i) { alert("found zrow"); }); }, "xml"); 

As Rich said:

The best solution does not require escaping and works in all "modern" browsers:

 .find("[nodeName=z:row]") 
+129
May 13, '09 at 14:31
source share

I spent several hours reading this about plugins and all kinds of solutions without any luck.

ArnisAndy posted a link to a jQuery discussion where this answer is suggested, and I can confirm that this works for me in Chrome (v18.0), FireFox (v11.0), IE (v9.08) and Safari (v5.1.5) using jQuery (v1.7.2).

I am trying to clear a WordPress feed where the content is called <content: encoded> and this is what worked for me:

 content: $this.find("content\\:encoded, encoded").text() 
+33
May 7 '12 at 20:02
source share

Although the answer above seems correct, it does not work in webkit browsers (Safari, Chrome). The best solution that I think would be:

 .find("[nodeName=z:myRow, myRow]") 
+19
Dec 14 '09 at 16:24
source share

If you are using jquery 1.5, you will need to add quotes around the value of the attribute of the node selector to make it work:

 .find('[nodeName="z:row"]') 
+19
Mar 12 '11 at 1:16
source share

If someone needs to do this without jQuery , just with plain Javascript, and for Google Chrome (webkit) , this is the only way to find it working after a lot of research and testing.

parentNode.getElementsByTagNameNS("*", "name");

This will work to get the following node: <prefix:name> . As you can see, the prefix or namespace is omitted, and it will match elements with different namespaces if the name tag is name . But hopefully this will not be a problem for you.

None of this worked for me (I am developing a Google Chrome extension):

getElementsByTagNameNS("prefix", "name")

getElementsByTagName("prefix:name")

getElementsByTagName("prefix\\:name")

getElementsByTagName("name")

Edit : after some sleep, I found a workaround :). This function returns the first node corresponding to the full nodeName , for example, <prefix:name> :

 // Helper function for nodes names that include a prefix and a colon, such as "<yt:rating>" function getElementByNodeName(parentNode, nodeName) { var colonIndex = nodeName.indexOf(":"); var tag = nodeName.substr(colonIndex + 1); var nodes = parentNode.getElementsByTagNameNS("*", tag); for (var i = 0; i < nodes.length; i++) { if (nodes[i].nodeName == nodeName) return nodes[i] } return undefined; } 

It can be easily changed if you need to return all the relevant elements. Hope this helps!

+15
Jul 25 2018-11-11T00:
source share

None of the above solutions work so well. I found this and was improved for speed. just add this while working like a charm:

 $.fn.filterNode = function(name) { return this.find('*').filter(function() { return this.nodeName === name; }); }; 

using:

 var ineedthatelementwiththepsuedo = $('someparentelement').filterNode('dc:creator'); 

source: http://www.steveworkman.com/html5-2/javascript/2011/improving-javascript-xml-node-finding-performance-by-2000/

+13
Jul 22 '13 at 16:56
source share

"\\" shielding is not reliable and simple

 .find('[nodeName="z:row"]') 

The method seems to have been broken as jQuery 1.7. I was able to find a solution for 1.7 using the filter function, here: Improving Javascript XML Node Performance Search

+9
Dec 14 2018-11-12T00:
source share

It is worth noting that with jQuery 1.7 there were problems with some common tasks for finding elements with names. See these links for more information:

+3
Mar 26 2018-12-21T00:
source share

Solution found in comment: XML parsing with namespaces using jQuery $ (). find

Using the second half of the node name after the colon worked for me. .find ("lat") instead of .find ("geo \: lat") , and it worked for me.




My setup:

  • Chrome 42
  • jQuery 2.1.3

XML example (snippet from the Google Contacts API):

 <entry> <id>http://www.google.com/m8/feeds/contacts/mstefanow%40gmail.com/base/0</id> <gd:email rel="http://schemas.google.com/g/2005#other" address="email@example.com" primary="true"/> </entry> 

Code Analysis:

 var xmlDoc = $.parseXML( xml ); var $xml = $( xmlDoc ); var $emailNode = $xml.find( "email" ); $("#email").html($emailNode.attr("address")); 

Plnkr: http://plnkr.co/edit/l8VzyDq1NHtn5qC9zTjf?p=preview

+3
May 4 '15 at
source share

jQuery 1.7 does not work with the following:

 $(xml).find("[nodeName=a:IndexField2]") 

One of the solutions I made to work in Chrome, Firefox, and IE is to use selectors that work in IE and selectors that work in Chrome, based on the fact that one of the methods works in IE and the other in Chrome:

 $(xml).find('a\\\\:IndexField2, IndexField2') 

In IE, this returns nodes using a namespace (Firefox and IE require a namespace), and in Chrome, the selector returns nodes based on a nameless selector. I have not tested this in Safari, but it should work because it works in Chrome.

+2
Jul 25 '12 at 23:44
source share

My solution (because I use a php proxy) is to replace: namespace with _... so there is no more namespace; -)

Keep it simple!

+2
Nov 09 '12 at 16:25
source share

Original answer: jQuery XML parsing how to get element attribute

Here is an example of how to successfully get value in Chrome ..

  item.description = jQuery(this).find("[nodeName=itunes\\:summary]").eq(0).text(); 
+2
Mar 13 '13 at 21:50
source share

As of early 2016, for me, the following syntax works with jQuery 1.12.0:

  • IE 11 (11.0.9600.18204, Update 11.0.28, KB3134815): .find("z\\:row")
  • Firefox 44.0.2: .find("z\\:row")
  • Chrome 44.0.2403.89m: .find("row")

The .find("[nodeName=z:row]") syntax .find("[nodeName=z:row]") does not work in any of the browsers mentioned above. I did not find a way to apply the namespace in Chrome.

Putting it all together, the following syntax works in all of the browsers listed above: .find("row,z\\:row")

+2
Feb 23 '16 at 10:07
source share

As mentioned above, there are problems with the above solution with current browsers / versions of jQuery - the proposed plug-in does not fully work either because of problems with the case ( nodeName , as a property, sometimes in all uppercase). So, I wrote the following quick function:

 $.findNS = function (o, nodeName) { return o.children().filter(function () { if (this.nodeName) return this.nodeName.toUpperCase() == nodeName.toUpperCase(); else return false; }); }; 

Usage example:

 $.findNS($(xml), 'x:row'); 
+1
Apr 24 2018-12-21T00:
source share

Contents: $this.find("content\\:encoded, encoded").text()

- the perfect solution ...

+1
Apr 23 '14 at 9:41
source share

JQuery has a jquery-xmlns plugin for working with namespaces in selectors.

+1
Jun 22 '17 at 16:54 on
source share

I have not seen any documentation on using jQuery to parse XML. JQuery usually uses Browser dom to view the HTML document, I do not believe that it reads html itself.

You should probably take a look at the built-in XML processing in JavaScript itself.

http://www.webreference.com/programming/javascript/definitive2/

0
May 12 '09 at
source share

just replaced the namespace with an empty string. Works great for me. Tested solution in browsers: Firefox, IE, Chrome

My task was to read and parse the EXCEL file through the Sharepoint EXCEL REST API. The XML response contains tags with the namespace "x:".

I decided to replace the namespace in XML with an empty string. It works like this: 1. Get the node interest from the XML response 2. Convert the selected node XML-Response (Document) to String 2. Replace the namespace with the empty string 3. Convert the string back to the XML document

See the code diagram here →

 function processXMLResponse)(xData) { var xml = TOOLS.convertXMLToString("", "",$(xData).find("entry content")[0]); xml = xml.replace(/x:/g, ""); // replace all occurences of namespace xData = TOOLS.createXMLDocument(xml); // convert string back to XML } 

To convert XML-to-String, find the solution here: http://www.sencha.com/forum/showthread.php?34553-Convert-DOM-XML-Document-to-string

0
Jun 08 '13 at 17:59
source share

Alternatively, you can use fast-xml-parser in your project and convert the XML data to a JS / JSON object. Then you can use it as a property of an object. It does not use jQuery or other libraries, but it will solve your goal.

 var xmlData = '<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">' +' <s:Schema id="RowsetSchema">' +' <s:ElementType name="row" content="eltOnly" rs:CommandTimeout="30">' +' <s:AttributeType name="ows_ID" rs:name="ID" rs:number="1">' +' <s:datatype dt:type="i4" dt:maxLength="4" />' +' </s:AttributeType>' +' <s:AttributeType name="ows_DocIcon" rs:name="Type" rs:number="2">' +' <s:datatype dt:type="string" dt:maxLength="512" />' +' </s:AttributeType>' +' <s:AttributeType name="ows_LinkTitle" rs:name="Title" rs:number="3">' +' <s:datatype dt:type="string" dt:maxLength="512" />' +' </s:AttributeType>' +' <s:AttributeType name="ows_ServiceCategory" rs:name="Service Category" rs:number="4">' +' <s:datatype dt:type="string" dt:maxLength="512" />' +' </s:AttributeType>' +' </s:ElementType>' +' </s:Schema>' +' <rs:data>' +' <z:row ows_ID="2" ows_LinkTitle="Sample Data 1" />' +' <z:row ows_ID="3" ows_LinkTitle="Sample Data 2" />' +' <z:row ows_ID="4" ows_LinkTitle="Sample Data 3" />' +' </rs:data>' +'</xml>' var jsObj = parser.parse(xmlData,{attrPrefix:"",ignoreTextNodeAttr: false}); document.write(JSON.stringify(jsObj.xml["rs:data"]["z:row"][0],null,4) + "<br>"); document.write(JSON.stringify(jsObj.xml["rs:data"]["z:row"][1],null,4) + "<br>"); document.write(JSON.stringify(jsObj.xml["rs:data"]["z:row"][2],null,4) + "<br>"); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/fast-xml-parser/2.9.2/parser.min.js"></script> 

You can ignore namespaces when parsing js / json objects. In this case, you can get direct access as jsObj.xml.data.row .

 for(var i=0; i< jsObj.xml.data.row.length; i++){ console.log(jsObj.xml.data.row[i]); } 

Disclaimer : I created fast-xml-parser.

0
Jan 23 '18 at 4:19
source share

For Webkit browsers, you can just leave a colon. So, to find <media:content> in an RSS feed, for example, you can do this:

 $(this).find("content"); 
-one
Jul 18 '13 at 14:02
source share



All Articles