【问题标题】:Would schema issues prevent SelectNodes() from finding a node?架构问题会阻止 SelectNodes() 找到节点吗?
【发布时间】:2017-08-29 22:19:29
【问题描述】:

我有一些非常基本的 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() 错过我的节点?第二个问题:我该如何解决?

【问题讨论】:

    标签: c# xml xpath schema


    【解决方案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 更简洁的 API,并且提供比 XPath 更好的查询语言。此代码将为您提供整数形式的错误代码:

    var doc = XDocument.Parse(xmlString);
    
    XNamespace api = "http://platform.intuit.com/api/v1";
    
    var errorCode = (int) doc.Descendants(api + "ErrorCode").Single();
    

    【讨论】:

    • 不知道为什么我没有发现 LINQ to XML - 显然是要走的路!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-01
    • 1970-01-01
    • 2014-11-03
    • 2015-06-07
    • 2013-09-15
    • 2011-03-22
    • 1970-01-01
    相关资源
    最近更新 更多