I\'m new to jQuery and would like to parse an XML document.
I\'m able to parse regular XML with the default namespaces but with XML such as:
Found solution in the comment: Parsing XML with namespaces using jQuery $().find
Using the second half of node name after the colon worked for me. Used .find("lat") instead of .find("geo\:lat") and it worked for me.
My setup:
Sample XML (snippet from 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>
Parsing code:
var xmlDoc = $.parseXML( xml );
var $xml = $( xmlDoc );
var $emailNode = $xml.find( "email" );
$("#email").html($emailNode.attr("address"));
Although the above answer seems to be correct, it does not work in webkit browsers (Safari, Chrome). A better solution I believe would be:
.find("[nodeName=z:myRow, myRow]")
There is a plugin jquery-xmlns for jQuery to work with namespaces in selectors.
The "\\" escaping isn't foolproof and the simple
.find('[nodeName="z:row"]')
Method seems to have been broken as of Jquery 1.7. I was able to find a solution for 1.7 , using a filter function, here: Improving Javascript XML Node Finding Performance
In case someone needs to do this without jQuery, just with normal Javascript, and for Google Chrome (webkit), this is the only way I found to get it to work after a lot of research and testing.
parentNode.getElementsByTagNameNS("*", "name");
That will work for retrieving the following node: <prefix:name>
. As you can see the prefix or namespace is omitted, and it will match elements with different namespaces provided the tag name is name
. But hopefully this won't be a problem for you.
None of this worked for me (I am developping a Google Chrome extension):
getElementsByTagNameNS("prefix", "name")
getElementsByTagName("prefix:name")
getElementsByTagName("prefix\\:name")
getElementsByTagName("name")
Edit: after some sleep, I found a working workaround :) This function returns the first node matching a full nodeName
such as <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 easily be modified in case you need to return all the matching elements. Hope it helps!
As mentioned above, there are problems with the above solution with current browsers/versions of jQuery - the suggested plug-in doesn't completely work either because of case issues (nodeName
, as a property, is sometimes in all upper case). 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;
});
};
Example usage:
$.findNS($(xml), 'x:row');