2015-08-15 78 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); 
} 
相關問題