我有一些非常基本的XML:
<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 Tools插件的Notepad ++,所以让我们在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()
错过我的节点?次要问题:我该如何解决?
答案 0 :(得分: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 to XML比XmlDocument
更清晰,并提供比XPath更好的查询语言。此代码将为您提供整数错误代码:
var doc = XDocument.Parse(xmlString);
XNamespace api = "http://platform.intuit.com/api/v1";
var errorCode = (int) doc.Descendants(api + "ErrorCode").Single();