2012-05-19 47 views
2

我正在寫一個JavaScript小程序中,我想解析以下的小XML片段:getAttributeNS的行爲是什麼?

<iq xmlns="jabber:client" other="attributes"> 
    <query xmlns="jabber:iq:roster"> 
    <item subscription="both" jid="[email protected]"></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應返回值[email protected]

[更新]問題是(或者是)我對命名空間與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

我沒有使用XML命名空間的經驗,但從我從線上演示中看到的第一個參數(它代表XML名稱空間)是一個URI。 –

+1

@ŠimeVidas命名空間'jabber:iq:roster'是在[XMPP](http://xmpp.org/rfcs/rfc6121.html#roster-syntax-actions-get)規範中定義的正確URI。 –

回答

5

重要的是,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="[email protected]"></a:item> 
</a:query> 

這裏有更多關於這個問題的一些:XML namespaces and attributes

如果您只想使用名稱空間感知方法,那麼它應該(不確定,但可能是實現特定的)爲null命名空間爲您工作。試試getAttributeNS(null, "jid")。如果沒有,您可以隨時使用hasAttributeNS()解決此問題,然後才能回退到getAttributeNS()getAttribute()

+0

首先感謝我指出了XML **的命名空間規範。我想我對XML屬性內的命名空間的理解是錯誤的(至少我現在很困惑)。 ;-)但是,這個短語對前綴屬性的解釋是由它們出現的元素決定的。 –

+0

我想這意味着屬性屬於一個元素而不是一個名稱空間。當然,也有例外情況,例如'xml:lang',但大多數屬性僅在特定元素的上下文中才有意義。 –