我创建了一些实现IXmlSerializable的专用数据结构。在运行时,我想将这些实例序列化为单个XML文档(并反序列化)。
序列化到不同的文件,XML结果是正确的。但是当我尝试在单个XmlSerializer.Serialize
上为不同的数据结构连续调用StreamWriter
时,结果是它在每次调用时都添加了XML声明,导致XML无效。
这样做的正确方法是什么?
我需要一个包装父类吗?如果我使用另一个父类来包装这些数据结构,然后序列化父类,我应该如何在父类中编写实现IXmlSerialize
?
答案 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);
}