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

时间:2015-08-15 18:04:34

标签: c# xml xmlserializer

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

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

这样做的正确方法是什么?

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

2 个答案:

答案 0 :(得分:1)

  

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

是。 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();

保存,如你所愿。

答案 1 :(得分:0)

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

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