如何将多个IXmlSerializable序列化为一个XML文件
本文关键字:一个 文件 XML 序列化 IXmlSerializable | 更新日期: 2023-09-27 18:08:09
我已经创建了一些实现IXmlSerializable的专用数据结构。在运行时,我希望将这些实例序列化为单个XML文档(并进行反序列化)。
序列化到不同的文件,XML结果是正确的。但是,当我尝试在不同数据结构的单个StreamWriter
上连续调用XmlSerializer.Serialize
时,结果是它在每次调用时都添加了XML声明,从而导致无效的XML。
正确的方法是什么?
我需要一个包装器父类吗?如果我使用另一个父类来包装这些数据结构,然后序列化父类,我应该如何在父类中编写实现IXmlSerialize
?
我需要一个包装器父类吗?
是的。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);
}