2015-08-15 126 views
1

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

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

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

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

回答

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

保存,作为你喜欢。

+0

XML只能有一个根标记。所以你不能使用序列化程序将多个xml放入同一个文件。唯一的选择是封装父类。 – jdweng

+0

这是我的答案,对不对? @jdweng –

+0

那么,你需要确实实现'IXmlSerialize'。或者使用'sgen'生成一个序列化类并删除你不想要的字段(请不要)。 –

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); 
} 
相关问题