Каково поведение getAttributeNS?

Я пишу небольшую программу на JavaScript, в которой я хочу проанализировать следующий небольшой фрагмент XML:

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

Поскольку я не знаю, если элементы и атрибуты имеют префиксы пространства имен, я использую функции, учитывающие пространство имен (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');
  };
};

С этим кодом я не получаю значение атрибута jid (Я получаю пустую строку), но когда я использую itemElement.getAttribute('jid') вместо itemElement.getAttributeNS('jabber:iq:roster', 'jid') Я получаю ожидаемый результат.

Как я могу написать код с учетом пространства имен? В моем понимании XML, пространство имен атрибута jid имеет пространство имен jabber:iq:roster и, следовательно, функция getAttributeNS должен вернуть значение romeo@example.com,

[ОБНОВЛЕНИЕ] Проблема была (или есть) в моем понимании использования пространств имен вместе с атрибутами XML и не связано с API DOM. Для этого я создал другой вопрос: пространства имен XML и атрибуты без префиксов. Кроме того, потому что пространства имен и атрибуты XML, к сожалению, не дают мне ответа.

[ОБНОВЛЕНИЕ] Что я сделал сейчас, так это сначала проверил, есть ли атрибут без пространства имен, а затем, если он там с пространством имен:

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

  };
};

1 ответ

Решение

Важно то, что атрибуты не получают пространство имен, пока вы явно не добавите им префикс:

A default namespace declaration applies to all unprefixed element names within its scope. Default namespace declarations do not apply directly to attribute names

Это отличается от элементов, которые наследуют пространство имен по умолчанию от родителя, если только они не определены самостоятельно. С учетом сказанного, ваши атрибуты не являются пространством имен, и именно поэтому getAttribute() работает и getAttributeNS() со значением пространства имен нет.

Ваш исходный XML должен выглядеть примерно так, чтобы "пространство имен" атрибута:

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

Вот еще немного по теме: пространства имен XML и атрибуты.

Если вы хотите использовать только методы, учитывающие пространство имен, тогда он должен (хотя и не уверен, что может зависеть от реализации) работать с вами null Пространство имен. Пытаться getAttributeNS(null, "jid"), Если это не так, вы всегда можете обойти это с hasAttributeNS() и только тогда отступление к getAttributeNS() или же getAttribute(),

Другие вопросы по тегам