我正在用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属性的理解,并且与DOM API无关。因此,我创建了另一个问题:XML Namespaces and Unprefixed Attributes。另外因为XML namespaces and attributes遗憾的是没有给我答案。
[更新]我现在所做的是首先检查是否存在没有命名空间的属性,然后是否有命名空间:
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');
};
};
答案 0 :(得分:6)
重要的是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
这与从父级继承默认命名空间的元素不同,除非有自己的定义。话虽如此,您的属性不是命名空间,这就是为什么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 namespaces and attributes。
如果您只想使用名称空间感知方法,那么它应该(不确定,可能是特定于实现)适用于null
命名空间。试试getAttributeNS(null, "jid")
。如果没有,您可以随时使用hasAttributeNS()
解决问题,然后再回退到getAttributeNS()
或getAttribute()
。