Каково поведение 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()
,