2010-01-11 74 views
3

我遇到XPathNavigator問題。我有一個文件,在流中有一堆「主題」元素w/o名稱空間。無法讓.NET XPathNavigator工作

我使用(表達簡單化到最低限度,開始我還以爲我的表達是錯誤的):

XPathDocument xmlDoc = new XPathDocument(stream); 
XPathNavigator xml = xmlDoc.CreateNavigator(); 
XPathNodeIterator iter = xml.Select("//topic"); 

這是行不通的。我可以選擇*/*/*或類似的東西,並獲得我的「主題」元素。 我試着在線測試儀和其他語言運行我的表達式,他們的工作。

問題:怎麼了?我一直懷疑它與被命名的NamespaceManager對象有關,每當我用命名空間解析文檔時,這會導致令人難以置信的痛苦,但是這次我所尋找的元素沒有明確的命名空間! 我說:

XmlNamespaceManager s = new XmlNamespaceManager(xml.NameTable); 

,並通過作爲第二個參數來選擇 - 無濟於事。我應該如何向這個東西添加「」命名空間/正確使用它?

或者更好的是,有沒有辦法在.NET中使用XPath,而沒有像使用其他語言一樣使用該類的可怕憎惡?如果我想命名空間,我可以寫他們在表達...

更新: 我想通了,從根節點workaround-複製/粘貼默認的xmlns,然後使用該命名空間:

thisIsRetarded.AddNamespace("x", "urn:xmind:xmap:xmlns:content:2.0"); 
XPathNodeIterator projectIter = projectTree.Select("//x:topic", thisIsRetarded); 

然而,我既不知道默認的URI,也不喜歡用不必要的x:-s來污染我的表達式。所以我現在只需要回答問題的第二部分。

+0

您_are_應該知道的命名空間。如果名稱空間不同,則兩個具有相同名稱的元素是_different_。 – 2010-01-11 01:09:03

+1

我很抱歉地說,命名變量thisIsRetarded對程序員來說只是錯誤的態度。事情並沒有因爲你沒有理解它們而遲鈍。 – Tomalak 2010-01-11 09:14:14

+2

但是,如果元素在xml文檔中沒有前綴,並且必須在xpath api中創建一些人造構造來選擇它,它*就相當愚蠢。 – 2010-10-26 13:17:17

回答

4

我更喜歡使用XmlDocument

XmlDocument doc = new XmlDocument(); 
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable); 
nsmgr.AddNamespace("sample", "..."); 
doc.Load(stream); 

XmlNode topic = doc.SelectSingleNode("/sample:topic", nsmgr); 

// If you don't have any namespaces.... 
XmlNode topic2 = doc.SelectSingleNode("/topic"); 
+0

重要的部分是 - 如果你有命名空間,那麼你需要在你的XPATH表達式中引用它們! – 2010-01-11 00:43:41

+0

+1我討厭XPathNavigator對象,除了命名空間 – 2010-02-25 06:07:28