2017-04-04 65 views
0

我有一些非常基本的XML:模式問題是否會阻止SelectNodes()查找節點?

<ReconnectResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://platform.intuit.com/api/v1">  
    <ErrorMessage/>  
    <ErrorCode>0</ErrorCode>  
    <ServerTime>2012-01-04T19:21:21.0782072Z</ServerTime>  
    <OAuthToken>redacted</OAuthToken>  
    <OAuthTokenSecret>redacted</OAuthTokenSecret> 
</ReconnectResponse> 

簡單,對不對?

所以當我想要得到ErrorCode的值時,我的XPath經驗告訴我試試/ReconnectResponse/ErrorCode/text()。這個工程在記事本++配備了XML工具插件,所以讓我們嘗試在C#:

var xmlDoc = new XmlDocument(); 
xmlDoc.LoadXml(xmlString); 
var namespaceMan = new XmlNamespaceManager(xmlDoc.NameTable); 
Console.WriteLine(xmlDoc.SelectSingleNode(@"/ReconnectResponse/ErrorCode", namespaceMan).InnerText); 

我得到一個異常:未設置爲一個對象的實例

對象引用。

這聽起來像是發現指定節點的問題。鑑於XML是多麼簡單,我正在努力解決出了什麼問題。

一時興起,我將XML放入XMLQuire。這會給每種元素類型帶來XSD架構錯誤,如下所示:

無法找到元素'http://platform.intuit.com/api/v1:ReconnectResponse'的模式信息。

所以,我的問題是模式錯誤是否可能導致SelectSingleNode()錯過我的節點?次要問題:我該如何解決它?

回答

1

您已經忽略了您的元素的命名空間,在這種情況下是http://platform.intuit.com/api/v1。這由根元素中的xmlns=".."屬性定義,並且所有子元素都繼承此屬性。

您需要將此命名空間添加到命名空間管理與前綴:

namespaceMan.AddNamespace("api", "http://platform.intuit.com/api/v1"); 

而且在查詢中使用這個前綴:

xmlDoc.SelectSingleNode(@"/api:ReconnectResponse/api:ErrorCode", namespaceMan).InnerText; 

順便說一句,LINQ到XML是一個遠比XmlDocument更清潔的API,並提供比XPath更好的查詢語言。這段代碼,會得到錯誤代碼爲整數:

var doc = XDocument.Parse(xmlString); 

XNamespace api = "http://platform.intuit.com/api/v1"; 

var errorCode = (int) doc.Descendants(api + "ErrorCode").Single(); 
+0

不知道爲什麼我沒有斑的LINQ to XML - 顯然是要走的路! –