4

我正在用 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应该返回 value romeo@example.com

[更新] 问题是(或者是)我对名称空间与 XML 属性一起使用的理解,并且与 DOM API 无关。因此,我创建了另一个问题:XML Namespaces and Unprefixed Attributes。也因为不幸的是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');

  };
};
4

1 回答 1

6

重要的是,除非您明确地为其添加前缀,否则属性不会获得名称空间

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")。如果没有,您始终可以使用 the 来解决它,hasAttributeNS()然后才回退到getAttributeNS()or getAttribute()

于 2012-05-19T13:55:51.427 回答