2010-05-14 88 views
1

我提供給我下面的XML和我不能改變它:查詢的值,其中默認命名空間節點存在

<Parent> 
    <Settings Version="1234" xmlns="urn:schemas-stuff-com"/> 
</Parent> 

我試圖取回使用XPath「版本」的屬性值。由於xmlns沒有別名定義,它會自動將xmlns分配給Settings節點。當我將這個XML讀入XMLDocument並查看Settings節點的namespaceURI值時,它被設置爲「urn:schemas-stuff-com」。

我曾嘗試:

//父/設置/ @版本- 返回Null

//父/甕:架構 - 東西-COM:設置/ @版本- 無效語法

+0

好的問題(+1)。查看我的答案,瞭解不依賴於特定實現或特定編程語言的解決方案。 :) – 2010-05-15 16:09:06

回答

0

解決方案取決於您正在使用的XPath版本。在XPath 2.0以下應該工作:

declare namespace foo = "urn:schemas-stuff-com"; 
xs:string($your_xml//Parent/foo:Settings/@Version) 

在XPath 1.0,而另一方面,唯一的解決辦法我已經成功地得到工作是:

//Parent/*[name() = Settings and namespace-uri() = "urn:schemas-stuff-com"]/@Version 

在我看來,該當XPath處理器在節點間更改時不會更改默認名稱空間,但我不確定這是否真的如此。

希望這會有所幫助。

+0

'namespace()'應該是'namespace-uri()'。 – 2010-05-14 22:53:21

+0

@Mads Hansen - 當然你是對的。固定。 – finrod 2010-05-15 08:22:14

+0

由於其他一些原因,我不得不動態創建「foo」命名空間名稱,而我不想這麼做,所以我最終使用了XPath 1.0語法。你的例子中有一個錯字,但是「Settings」應該用單引號括起來。 感謝您的幫助。 – Jay 2010-05-17 11:41:23

0

使用的XmlNamespaceManager的:

XmlDocument doc = new XmlDocument(); 
doc.Load("file.xml"); 

XmlNamespaceManager mgr = new XmlNamespaceManager(doc.NameTable); 
mgr.AddNamespace("foo", "urn:schemas-stuff-com"); 

XmlElement settings = doc.SelectSingleNode("Parent/foo:Settings", mgr) as XmlElement; 
if (settings != null) 
{ 
    // access settings.GetAttribute("version") here 
} 

// or alternatively select the attribute itself with XPath e.g. 
XmlAttribute version = doc.SelectSingleNode("Parent/foo:Settings/@Version", mgr) as XmlAttribute; 
if (version != null) 
{ 
    // access version.Value here 
} 
0

除了馬丁Honnen的正確答案,不幸的是執行和編程語言特定,這裏是一個純粹的XPath的解決方案

/*/*[name()='Settings ']/@Version 
+0

這與我的下面非常相似,只有它(可能)也可以捕捉其他節點 – finrod 2010-05-15 20:52:01