I’m writing a little program in JavaScript in which I want to parse the following little XML snippet:
<iq xmlns="jabber:client" other="attributes">
<query xmlns="jabber:iq:roster">
<item subscription="both" jid="romeo@example.com"></item>
</query>
</iq>
Because I don’t know, if the elements and attributes have namespace prefixes, I’m using the namespace-aware functions (getElementsByTagNameNS, getAttributeNS).
var queryElement = iq.getElementsByTagNameNS('jabber:iq:roster', 'query')[0];
if (queryElement) {
var itemElements = queryElement.getElementsByTagNameNS('jabber:iq:roster', 'item');
for (var i = itemElements.length - 1; i >= 0; i--) {
var itemElement = itemElements[i];
var jid = itemElement.getAttributeNS('jabber:iq:roster', 'jid');
};
};
With this code I don’t get the value of the attribute jid (I get an empty string), but when I use itemElement.getAttribute('jid') instead of itemElement.getAttributeNS('jabber:iq:roster', 'jid') I’m getting the expected result.
How can I write the code in a namespace-aware manner? In my understanding of XML, the namespace of the attribute jid has the namespace jabber:iq:roster and therefore the function getAttributeNS should return the value romeo@example.com.
[UPDATE] The problem was (or is) my understanding of the use of namespaces together with XML attributes and is not related to the DOM API. Therefor I created an other question: XML Namespaces and Unprefixed Attributes. Also because XML namespaces and attributes unfortunately doesn’t give me an answer.
[UPDATE] What I did now, is to first check if there is the attribute without a namespace and then if it is there with a namespace:
var queryElement = iq.getElementsByTagNameNS('jabber:iq:roster', 'query')[0];
if (queryElement) {
var itemElements = queryElement.getElementsByTagNameNS('jabber:iq:roster', 'item');
for (var i = itemElements.length - 1; i >= 0; i--) {
var itemElement = itemElements[i];
var jid = itemElement.getAttribute('jid') || itemElement.getAttributeNS('jabber:iq:roster', 'jid');
};
};
The important thing is that attributes don’t get the namespace until you explicitly prefix them with it:
A default namespace declaration applies to all unprefixed element names within its scope. Default namespace declarations do not apply directly to attribute namesThis is unlike elements that do inherit the default namespace from the parent unless have their own defined. With that said, your attributes are not namespaced and that’s why
getAttribute()works andgetAttributeNS()with a namespace value doesn’t.Your source XML would need to look something like this to “namespace” the attribute:
Here’s some more on the subject: XML namespaces and attributes.
If you want to only use the namespace-aware methods then it should (not sure though, might be implementation specific) work for you with
nullnamespace. TrygetAttributeNS(null, "jid"). If it doesn’t, you can always work around it with thehasAttributeNS()and only then a fallback togetAttributeNS()orgetAttribute().