【问题标题】:Behavior of LoadXml and SelectNodesLoadXml 和 SelectNode 的行为
【发布时间】:2016-07-06 07:26:20
【问题描述】:

我有类似于下面第一个的代码

String xml1 =
    @"<resultset>
        <result>
            <alamakota />
        </result>
    </resultset>";
String xml2 =
    @"<resultset/>";
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(xml1);
XmlNodeList nodes1 = xDoc.SelectNodes("/resultset/result");
xDoc.LoadXml(xml2);
XmlNodeList nodes2 = xDoc.SelectNodes("/resultset/result");
Console.WriteLine(nodes1.Count);
Console.WriteLine(nodes2.Count);

我希望 WriteLine 方法给出 1 和 0,但并非总是如此。在正常程序运行中,它会给出双 0。同样在调试期间,当我在第二个 SelectNodes 上放置断点并检查 VS 中的 nodes1.Count 值时,它最后给了我 1 和 0。似乎 SelectNodes 在第一次检查 XmlNodeList 时被评估,而不是在代码中的位置,例如下面的代码每次运行时都会给出 1 和 0

String xml1 =
    @"<resultset>
        <result>
            <alamakota />
        </result>
    </resultset>";
String xml2 =
    @"<resultset/>";
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(xml1);
XmlNodeList nodes1 = xDoc.SelectNodes("/resultset/result");
Int32 c1 = nodes1.Count;
xDoc.LoadXml(xml2);
XmlNodeList nodes2 = xDoc.SelectNodes("/resultset/result");
Console.WriteLine(nodes1.Count);
Console.WriteLine(nodes2.Count);

我知道我可以在第一个 SelectNodes 之后执行 xDoc = new XmlDocument() 并且它会像预期的那样工作,但我想知道它是否应该这样工作,因为我在 msdn 上找不到这种情况。如果是,那为什么?请指点我一些文档。

【问题讨论】:

  • 出于兴趣,您有什么理由不能使用 LINQ to XML?这通常是一个用于处理 XML 的更简洁的 API...
  • 技术上没有。这是我的选择,因为我在其他无法使用 LINQ 的系统中使用 XPath。
  • @pen2 - 您可以将 XPath 与 LINQ to XML 一起使用。参见例如How to use XPath with XElement or LINQ?

标签: c# xml .net-3.5 xmldocument selectnodes


【解决方案1】:

您所看到的已记录在案。

来自XmlNodeList的文档:

对创建XmlNodeList 集合的节点对象的子对象的更改立即反映在XmlNodeList 属性和方法返回的节点中。

来自XmlNode.SelectNodes()的文档

此方法返回的XmlNodeList 对象将有效,而基础文档保持不变。 如果底层文档发生变化,可能会返回意想不到的结果(不会抛出异常)。

因此,当您用全新的 XML 覆盖 xDoc 的内容时,Microsoft 不再定义先前创建的 XmlNodeList 的内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-03
    • 1970-01-01
    • 2014-05-03
    • 2015-09-16
    相关资源
    最近更新 更多