4

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');

  };
};
Community
  • 1
  • 1
Tobias Kräntzer
  • 1,694
  • 1
  • 13
  • 23
  • I have no experience with XML namespaces, but from what I'm seeing from demos online, the first argument (which represents the XML namespace) is an URI. – Šime Vidas May 19 '12 at 13:56
  • 1
    @ŠimeVidas The namespace 'jabber:iq:roster' is a correct URI defined in the specs of [XMPP](http://xmpp.org/rfcs/rfc6121.html#roster-syntax-actions-get). – Tobias Kräntzer May 20 '12 at 10:34

1 Answers1

6

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 names

This 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 and getAttributeNS() with a namespace value doesn't.

Your source XML would need to look something like this to "namespace" the attribute:

<a:query xmlns:a="jabber:iq:roster">
    <a:item a:subscription="both" a:jid="romeo@example.com"></a:item>
</a:query>

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 null namespace. Try getAttributeNS(null, "jid"). If it doesn't, you can always work around it with the hasAttributeNS() and only then a fallback to getAttributeNS() or getAttribute().

Community
  • 1
  • 1
Pavel Veller
  • 6,085
  • 1
  • 26
  • 24
  • First thanks for pointing me to the spec for **Namespaces in XML**. I guess my understanding of namespaces within XML attributes was wrong (at least I'm confused now). ;-) But what does the phrase _the interpretation of unprefixed attributes is determined by the element on which they appear._ mean? – Tobias Kräntzer May 20 '12 at 09:43
  • I guess it means that the attributes belong to an element rather than a namespace. There are exceptions, of course, like `xml:lang` for example, but the majority of attributes only make sense in context of a particular element. – Pavel Veller May 20 '12 at 12:31