2009-02-09 23 views
6

Tôi đã có một lớp cơ sở tương thích với tuần tự hóa XML và một lớp dẫn xuất có triển khai thực hiện IXmlSerializable.C# Xml-Tuần tự hóa một lớp dẫn xuất sử dụng IXmlSerializable

Trong ví dụ này, các lớp cơ sở không thực hiện IXmlSerializable:


using System.Diagnostics; 
using System.Text; 
using System.Xml; 
using System.Xml.Schema; 
using System.Xml.Serialization; 

namespace XmlSerializationDerived 
{ 
    public class Foo 
    { 
     public int fooProp; 

     public XmlSchema GetSchema() 
     { 
      return null; 
     } 

     public void ReadXml(XmlReader reader) 
     { 
      fooProp = int.Parse (reader.ReadElementString ("fooProp")); 
     } 

     public void WriteXml(XmlWriter writer) 
     { 
      writer.WriteElementString ("fooProp", fooProp.ToString()); 
     } 
    } 

    public class Bar : Foo, IXmlSerializable 
    { 
     public new void ReadXml(XmlReader reader) 
     { 
      base.ReadXml (reader); 
     } 

     public new void WriteXml(XmlWriter writer) 
     { 
      base.WriteXml (writer); 
     } 

     static void Main(string[] args) 
     { 
      StringBuilder sb = new StringBuilder(); 
      XmlWriter writer = XmlWriter.Create (sb); 

      Bar bar = new Bar(); 
      bar.fooProp = 42; 

      XmlSerializer serializer = new XmlSerializer (typeof (Bar)); 
      serializer.Serialize (writer, bar); 

      Debug.WriteLine (sb.ToString()); 
     } 
    } 
} 

này tạo ra sản lượng này:

<?xml version="1.0" encoding="utf-16"?><Bar><fooProp>42</fooProp></Bar> 

Tuy nhiên, tôi muốn sử dụng một lớp cơ sở mà không không triển khai IXmlSerializable. Điều này ngăn không cho sử dụng base.Read/WriteXml. Kết quả sẽ là:

<?xml version="1.0" encoding="utf-16"?><Bar /> 

Có cách nào để nhận kết quả mong muốn không?

Trả lời

2

"Điều này ngăn việc sử dụng base.Read/WriteXml".

Thông thường, nếu lớp cơ sở được triển khai IXmlSerializable, bạn có thể sử dụng phương thức virtual để phiên bản cụ thể được sử dụng. Thông thường, bạn cũng sử dụng việc thực hiện rõ ràng (thay vì các thuộc tính công khai) - có lẽ với một số phương thức protected virtual cho các chi tiết thực hiện (mặc dù theo dõi nơi người đọc/người viết ở các lớp khác nhau sẽ là một cơn ác mộng).

AFAIK, không có cách nào để tái sử dụng XmlSerializer để viết cơ sở bit, trong khi bạn thêm có nguồn gốc bit. IXmlSerializable là tất cả hoặc không có gì.

+0

Đến từ Java và nó dễ dàng chết serialization, tôi là một chút buồn khi nghe điều này. Tôi thực sự tạo ra lớp cơ sở, mà tôi may mắn có quyền truy cập, triển khai thực hiện IXmlSerializable. Nó hoạt động, nhưng nó rất đau, bởi vì tôi đang viết mã mà không được cho là tồn tại. – mafu

+0

Trừ khi có ai đó đưa ra một cách tiếp cận mới, đây là câu trả lời chính thức. – mafu

1

tại sao không chỉ đơn giản sử dụng XmlSerializer trong chức năng đọc/ghi của bạn?

XmlSerializer s = new XmlSerializer(typeof(Foo)); 
s.Serialize(writer, base); 
+1

Vì nó phải được tự tuần tự hóa vì lý do tôi không thể nhớ lại nữa. :) – mafu

4

Cải thiện câu trả lời của mtlung, tại sao bạn không sử dụng XmlSerializer? Bạn có thể điều chỉnh lớp của bạn với thuộc tính để nó có thể được sắp xếp theo cách bạn muốn, và nó khá đơn giản để làm.

using System.Xml.Serialization; 

... 

[XmlRoot("someclass")] 
public class SomeClass 
{ 
    [XmlAttribute("p01")] 
    public int MyProperty01 
    { 
     get { ... } 
    } 

    [XmlArray("sometypes")] 
    public SomeType[] MyProperty02 
    { 
     get { ... } 
    } 

    [XmlText] 
    public int MyProperty03 
    { 
     get { ... } 
    } 

    public SomeClass() 
    { 
    } 
} 

Sau đó, tuần tự và deserializing nó sẽ là khá đơn giản:

void Save(SomeClass obj) 
{ 
    XmlSerializer xs = new XmlSerializer(typeof(SomeClass)); 
    using (FileStream fs = new FileStream("c:\\test.xml", ...)) 
    { 
     xs.Serialize(fs, obj); 
    } 
} 

void Load(out SomeClass obj) 
{ 
    XmlSerializer xs = new XmlSerializer(typeof(SomeClass)); 
    using (FileStream fs = new FileStream("c:\\test.xml", ...)) 
    { 
     obj = xs.Deserialize(fs); 
    } 
} 

Và XML kết quả sẽ là một cái gì đó như thế này:

<someclass p01="..."> 
    <sometype> 
    <!-- SomeType serialized objects as child elements --> 
    </sometype> 
    # value of "MyProperty03" as text # 
</someclass> 

Phương pháp này hoạt động tốt hơn với "poco" các lớp học, và nó đơn giản và sạch sẽ. Bạn thậm chí không cần phải sử dụng các thuộc tính, chúng ở đó để giúp bạn tùy chỉnh tuần tự hóa.

Các vấn đề liên quan