我试图从根目录中移除所有子节点,而不是需要存在的节点,这是我写的
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方法有什么不同吗?哪个概念让我误解了......
答案 0 :(得分:2)
documentation on the SelectNodes
method说:
此方法返回的XmlNodeList对象有效,而基础文档保持不变。如果基础文档发生更改,则可能会返回意外结果(不会抛出任何异常)。
因此,似乎结果XmlNodeList
在某种程度上耦合到底层的Xml文档。通过致电RemoveAll
更改文档后,XmlNodeList
的特定行为无法保证。
因此,在您的情况下,在从文档中删除节点之前复制节点列表的内容应该是最安全的:
var nodes = nodeList.Cast<XmlNode>().ToArray();
这使用System.Linq.Enumerable
class中的一些扩展方法将XmlNodeList
的内容复制到一个新数组中(独立于Xml文档)。