如何将多个IXmlSerializable序列化为一个XML文件

本文关键字:一个 文件 XML 序列化 IXmlSerializable | 更新日期: 2023-09-27 18:08:09

我已经创建了一些实现IXmlSerializable的专用数据结构。在运行时,我希望将这些实例序列化为单个XML文档(并进行反序列化)。

序列化到不同的文件,XML结果是正确的。但是,当我尝试在不同数据结构的单个StreamWriter上连续调用XmlSerializer.Serialize时,结果是它在每次调用时都添加了XML声明,从而导致无效的XML。

正确的方法是什么?

我需要一个包装器父类吗?如果我使用另一个父类来包装这些数据结构,然后序列化父类,我应该如何在父类中编写实现IXmlSerialize ?

如何将多个IXmlSerializable序列化为一个XML文件

我需要一个包装器父类吗?

是的。XmlSerializer不是那么聪明。它输出一个XML文件。它没有考虑到它可能已经有了一些内容。您将在一个文件中得到两个XML文件。

事实上,如果你的数据结构很简单,你根本不需要实现IXmlSerializable。你可以序列化任何类。这个结构就足够了:

public class ParentClass
{
    public Class1 FirstClass {get;set;}
    public Class2 SecondClass {get;set;}
}

只要填入实例,就可以对它们进行XML序列化。


在我的例子中,我有一个扩展方法来为我完成所有的序列化。
public static string ToXml<T>(this T value)
{
    StringWriter stringWriter = new StringWriter();
    string xml;
    XmlSerializer xmlserializer = new XmlSerializer(typeof(T));
    using (XmlWriter writer = XmlWriter.Create(stringWriter, new XmlWriterSettings { Indent = true }))
    {
        writer.WriteStartDocument();
        xmlserializer.Serialize(writer, value);
        writer.WriteEndDocument();
        xml = stringWriter.ToString();
    }
    return xml;
}

然后你可以调用:

string xml = someInstanceOfParent.ToXml();

保存成你喜欢的样子

我们可以使用以下方法:在序列化时手动写入根节点,然后在反序列化时手动跳过该节点。

public class One
{
    public string Foo { get; set; }
}
public class Two
{
    public string Bar { get; set; }
}

var one = new One { Foo = "foo" };
var two = new Two { Bar = "bar" };
// Serialization two different class in one file
var settings = new XmlWriterSettings { Indent = true };
using (var writer = XmlWriter.Create("test.txt", settings))
{
    // Create root node
    writer.WriteStartElement("root");
    var xs = new XmlSerializer(typeof(One));
    xs.Serialize(writer, one);
    xs = new XmlSerializer(typeof(Two));
    xs.Serialize(writer, two);
}
// Deserialization two different class from one file
using (var reader = XmlReader.Create("test.txt"))
{
    // Skip root node
    reader.ReadToFollowing("One"); // Name of first class
    var xs = new XmlSerializer(typeof(One));
    One first = (One)xs.Deserialize(reader);
    xs = new XmlSerializer(typeof(Two));
    Two second = (Two)xs.Deserialize(reader);
}