You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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");
    }
}

关键注意事项

  1. 空值检查:加载XML后必须确认根节点、遍历的节点不为null,这是解决空引用的核心
  2. 节点导入:来自其他XmlDocument的节点必须用ImportNode导入,否则无法添加到目标文档
  3. 遍历修改集合:不能在遍历节点时直接移除元素,需要先收集再批量操作,避免集合修改异常
  4. 节点匹配规则:示例中用节点名称判断是否相同,你可以根据实际需求调整(比如对比节点的属性值、文本内容等)

内容的提问来源于stack exchange,提问作者CSharper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 08:54:22