C#中循环用AppendChild转移XML节点遇空引用异常求助
C# XML节点跨文件转移及AppendChild空引用异常解决
空引用异常的常见原因
你遇到的System.NullReferenceException通常是这几种情况:
- 加载XML后未检查根节点是否存在(比如文档为空或格式错误)
- 要添加的目标节点/源节点为null(比如遍历节点时没找到对应元素)
- 直接将其他XmlDocument的节点添加到目标文档,未做上下文导入(虽不会直接空引用,但可能引发后续异常,也可能间接导致节点获取失败)
正确实现步骤及代码示例
以下是符合你需求的完整实现,包含节点对比、差异转移、空值检查和文档保存:
using System; using System.Collections.Generic; using System.Xml; using System.IO; class XmlNodeTransfer { static void Main() { // 加载源XML和目标XML文档 XmlDocument sourceDoc = new XmlDocument(); XmlDocument targetDoc = new XmlDocument(); try { sourceDoc.Load("Source.xml"); targetDoc.Load("Target.xml"); } catch (FileNotFoundException ex) { Console.WriteLine($"错误:找不到文件 - {ex.FileName}"); return; } catch (XmlException ex) { Console.WriteLine($"XML格式错误:{ex.Message}"); return; } // 获取根节点,先做空值检查 XmlElement sourceRoot = sourceDoc.DocumentElement; XmlElement targetRoot = targetDoc.DocumentElement; if (sourceRoot == null || targetRoot == null) { Console.WriteLine("错误:XML文档缺少根节点"); return; } // 第一步:收集目标中不存在于源的节点,后续批量移除 List<XmlNode> nodesToRemove = new List<XmlNode>(); foreach (XmlNode targetNode in targetRoot.ChildNodes) { bool isMatch = false; foreach (XmlNode sourceNode in sourceRoot.ChildNodes) { // 这里用节点名称判断是否相同,你可以根据需求修改(比如属性、文本内容) if (targetNode.Name.Equals(sourceNode.Name, StringComparison.OrdinalIgnoreCase)) { isMatch = true; break; } } if (!isMatch) nodesToRemove.Add(targetNode); } // 批量移除目标中的差异节点(遍历过程中不能直接修改集合) foreach (XmlNode node in nodesToRemove) { targetRoot.RemoveChild(node); } // 第二步:添加源中不存在于目标的节点 foreach (XmlNode sourceNode in sourceRoot.ChildNodes) { bool isExist = false; foreach (XmlNode targetNode in targetRoot.ChildNodes) { if (sourceNode.Name.Equals(targetNode.Name, StringComparison.OrdinalIgnoreCase)) { isExist = true; break; } } if (!isExist) { // 必须导入节点到目标文档的上下文,否则会引发XmlException XmlNode importedNode = targetDoc.ImportNode(sourceNode, true); // true表示递归导入所有子节点 targetRoot.AppendChild(importedNode); } } // 保存到新文件 targetDoc.Save("NewCombined.xml"); Console.WriteLine("节点转移完成,已保存到NewCombined.xml"); } }
关键注意事项
- 空值检查:加载XML后必须确认根节点、遍历的节点不为null,这是解决空引用的核心
- 节点导入:来自其他XmlDocument的节点必须用
ImportNode导入,否则无法添加到目标文档 - 遍历修改集合:不能在遍历节点时直接移除元素,需要先收集再批量操作,避免集合修改异常
- 节点匹配规则:示例中用节点名称判断是否相同,你可以根据实际需求调整(比如对比节点的属性值、文本内容等)
内容的提问来源于stack exchange,提问作者CSharper
相关产品推荐
相关产品推荐

