2015-10-13 37 views
1

我正在使用XPATH 1.0從XML文檔中獲取某些節點,該文檔在根節點和具有屬性的節點上使用默認名稱空間。模式上設置了attributeFormDefault = "qualified"限定屬性的xpath

<Transaction xmlns="http://example.com/transaction"> 
    <someElement/> 
    <collection> 
     <value p0:Name="SomeName" xmlns:p0="http://example.com/transaction">some value</value> 
     <value p1:Name="SomeOtherName" xmlns:p1="http://example.com/transaction">some other value</value> 
    </collection> 
    <differentCollection> 
     <value p2:Name="SomeName" xmlns:p2="http://example.com/transaction">not this one</value> 
    </differentCollection> 
</Transaction> 

我的目的是得到/Transaction/collection/value[@Name='SomeName']節點。

到目前爲止我發現的唯一的解決辦法似乎有點寬泛:

//*[@*='SomeName'] 

我還可以通過使用得到<value>節點的整個集合:

//*[local-name()='value'] 

與命名空間限制在記住,是否有更清晰,更精確的方法來獲得我之後的節點?第三方JavaScript庫不是一個選項。


編輯

感謝您的快速反應。我會在這裏指出,通過添加默認的命名空間前綴,解決了XPath查詢表達式:

<t:Transaction xmlns:t="http://example.com/transaction"> 

現在我可以這樣做:

/t:Transaction/t:collection/t:value[@t:Name='SomeName'] 

回答

2

你真的想選擇以下:

/t:Transaction/t:collection/t:value[@t:Name = 'SomeName'] 

...因爲您已聲明t爲前綴評估XPath表達式之前的"http://example.com/transaction"名稱空間。

對於示例XML,您顯示可以將其壓縮到//t:value[@t:Name = 'SomeName']

在任何情況下,您都不會忽略輸入文檔中的名稱空間。 attributeFormDefault是一個紅鯡魚的問題。


如何定義選擇名稱空間取決於您用於評估XPath表達式的API。

瀏覽器集成的API支持名稱空間解析器函數,該函數將表達式中使用的前綴映射到相應的名稱空間URI。進一步閱讀:MDN: Introduction to using XPath in JavaScript

簡單的域名解析應該是這樣的:

function nsResolver(prefix) { 
    var ns = { 
     t: "http://example.com/transaction", 
    }; 
    return ns[prefix] || null; 
} 

注意,在XPath的命名空間前綴沒有與XML命名空間前綴同意。然而,他們指出的URI必須同意。

1

,而不是試圖裙子命名空間,follow best practices並綁定前綴使用命名空間前綴的命名空間,然後寫你的XPath:

  1. 綁定p0http://example.com/transaction使用機制 由您的XPath處理器提供。
  2. 然後利用在XPath表達式中的命名空間前綴:

    /p0:Transaction/p0:collection/p0:value[@p0:Name='SomeName']