XmlNode RemoveAll()使其他变量持有的节点的引用无效

时间:2015-08-24 19:04:23

标签: c# .net

我试图从根目录中移除所有子节点,而不是需要存在的节点,这是我写的

                XmlNode root = XmlTemplate.DocumentElement;

                string targetPrefix = root.Prefix;
                var xmlNamespaceManager = new XmlNamespaceManager(XmlTemplate.NameTable);
                xmlNamespaceManager.AddNamespace(root.Prefix, root.NamespaceURI);
                XmlNodeList nodeList = null;
                if (!String.IsNullOrEmpty(targetPrefix))
                {
                    nodeList = root.SelectNodes("descendant::" + targetPrefix + ":fields", xmlNamespaceManager);
                }
                else
                {
                    nodeList = root.SelectNodes("descendant::fields");
                }

正如所料,我能够在nodeList中获取所需的节点。我可以在调试模式下节点。下面的代码语句运行时会出现混淆

root.RemoveAll();
root.AppendChild(nodeList[0]);

根据我的理解,仍然在nodeList中引用子节点,因此对象不会被垃圾收集但在root.RmoveAll()执行后,nodeList变为空。

root.innexText ="";也做同样的事情

XML方法有什么不同吗?哪个概念让我误解了......

1 个答案:

答案 0 :(得分:2)

documentation on the SelectNodes method说:

  

此方法返回的XmlNodeList对象有效,而基础文档保持不变。如果基础文档发生更改,则可能会返回意外结果(不会抛出任何异常)。

因此,似乎结果XmlNodeList在某种程度上耦合到底层的Xml文档。通过致电RemoveAll更改文档后,XmlNodeList的特定行为无法保证。

因此,在您的情况下,在从文档中删除节点之前复制节点列表的内容应该是最安全的:

var nodes = nodeList.Cast<XmlNode>().ToArray();

这使用System.Linq.Enumerable class中的一些扩展方法将XmlNodeList的内容复制到一个新数组中(独立于Xml文档)。