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

如何将不同对象与DataSet序列化到同一XML并实现追加写入?

问题

需要用单个XML文件存储5个不同类型的类对象和1个DataSet的序列化值,要求每个对象(包括DataSet的内容)都有独立的根元素。目前已通过类上的XmlRoot特性实现对象序列化,但不知道如何让XmlSerializer或XmlWriter追加写入现有XML(不存在则创建)而非覆盖。

当前序列化类的代码:

var sts = new XmlWriterSettings() { Indent = true, OmitXmlDeclaration = true, };
var xs = new XmlSerializer(typeof(MyClassName));
var filename = "whatever.xml";
XmlWriter w = XmlWriter.Create(filename, sts);
xs.Serialize(w, objReference);
w.Close();

写入DataSet的代码:

var filename = "whatever.xml";
myDataSet.myTable.WriteXml(filename, XmlWriteMode.IgnoreSchema);
解决方案

首先明确:标准XML文档仅允许存在一个顶级根元素,因此不能直接追加多个独立根节点,必须先创建一个统一的根容器(例如<RootContainer>),所有对象和DataSet的序列化内容都作为该容器的子节点存在。

1. 初始化XML文件(首次创建)

如果目标文件不存在,先创建包含根容器的基础XML结构:

var filename = "whatever.xml";
if (!File.Exists(filename))
{
    using (var writer = XmlWriter.Create(filename, new XmlWriterSettings { Indent = true }))
    {
        writer.WriteStartDocument();
        writer.WriteStartElement("RootContainer"); // 定义统一根容器
        writer.WriteEndElement();
        writer.WriteEndDocument();
    }
}

2. 追加序列化的类对象

通过加载现有XML文档,将序列化后的对象节点插入根容器:

public void AppendObjectToXml<T>(T obj, string filename) where T : class
{
    var mainDoc = new XmlDocument();
    mainDoc.Load(filename);
    var rootContainer = mainDoc.DocumentElement; // 获取根容器节点

    // 将对象序列化为XmlNode
    var serializer = new XmlSerializer(typeof(T));
    using (var ms = new MemoryStream())
    {
        serializer.Serialize(ms, obj);
        ms.Position = 0;
        var objDoc = new XmlDocument();
        objDoc.Load(ms);
        
        // 将对象节点导入主文档并追加到根容器
        var importedNode = mainDoc.ImportNode(objDoc.DocumentElement, true);
        rootContainer.AppendChild(importedNode);
    }

    mainDoc.Save(filename);
}

调用示例:

var myObj = new MyClassName();
AppendObjectToXml(myObj, "whatever.xml");

3. 追加DataSet的内容

采用相同思路,将DataSet的XML内容作为子节点插入根容器:

public void AppendDataSetToXml(DataSet dataSet, string filename)
{
    var mainDoc = new XmlDocument();
    mainDoc.Load(filename);
    var rootContainer = mainDoc.DocumentElement;

    // 将DataSet内容序列化为XmlNode
    using (var ms = new MemoryStream())
    {
        dataSet.myTable.WriteXml(ms, XmlWriteMode.IgnoreSchema);
        ms.Position = 0;
        var dsDoc = new XmlDocument();
        dsDoc.Load(ms);
        
        // 导入DataSet节点并追加到根容器
        var importedNode = mainDoc.ImportNode(dsDoc.DocumentElement, true);
        rootContainer.AppendChild(importedNode);
    }

    mainDoc.Save(filename);
}

调用示例:

AppendDataSetToXml(myDataSet, "whatever.xml");

关键注意事项

  • 每个要序列化的类需保留XmlRoot特性,确保生成的节点符合预期结构
  • 操作XML时建议使用using语句,确保流和文档对象正确释放,避免文件锁问题
  • 每次追加操作都需重新加载整个XML文档,防止并发写入冲突

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 18:28:13