2009-04-22 32 views
13

Nói rằng tôi có một vài đối tượng cơ bản như sau:Làm thế nào để tôi deserialize XML mà không biết loại trước?

[Serializable] 
public class Base 
{ 

    public string Property1 { get; set; } 
    public int Property2 { get; set; } 
} 

[Serializable] 
public class Sub: Base 
{ 
    public List<string> Property3 { get; set; } 

    public Sub():base() 
    { 
     Property3 = new List<string>(); 
    }   
} 

Và tôi serialize họ như vậy:

Sub s = new Sub {Property1 = "subtest", Property2 = 1000}; 
s.Property3.Add("item 1"); 
s.Property3.Add("item 2"); 

XmlSerializer sFormater = new XmlSerializer(typeof(Sub)); 
using (FileStream fStream = new FileStream("SubData.xml", 
    FileMode.Create, FileAccess.Write, FileShare.None)) 
{ 
    sFormater.Serialize(fStream, s); 
} 

Làm thế nào tôi có thể deserialize họ, vì vậy mà tôi lấy lại lớp có đúng không?

Như trong, tôi muốn một cái gì đó như thế này

XmlSerializer bFormater = new XmlSerializer(typeof (Base)); 
Base newBase; 
using (FileStream fStream = new FileStream("BaseData.xml", 
    FileMode.Open, FileAccess.Read, FileShare.Read)) 
{ 
    newBase = (Base) bFormater.Deserialize(fStream); 
} 

Trừ tôi có thể vượt qua nó một file XML cho bất kỳ lớp đó xuống từ cơ sở và lớp đúng sẽ được tạo ra.

Tôi nghĩ mình có thể đọc tên của nút gốc của XML và sử dụng câu lệnh chuyển đổi để tạo XmlSerializer chính xác, nhưng tôi đã tự hỏi nếu có một cách đơn giản hơn.

+0

Ok. Mới kiểm tra. Nó ném một ngoại lệ. Đã xóa đoạn cuối cùng. – Kirtan

+0

Ok, đã xóa nhận xét của tôi vì nó không áp dụng nữa. – Ray

Trả lời

8

Sử dụng các thuộc tính [XmlInclude] trên lớp cơ sở của bạn để cho các serializer XML về các lớp thừa kế, vì vậy nó có thể tìm ra những gì để tạo ra. Đoạn mã cuối cùng của bạn sau đó sẽ hoạt động chính xác.

+0

Điều đó hoạt động tốt. Cảm ơn. – Ray

+1

Một điều nữa, khi tôi tuần tự hóa lớp con, tôi cần thực hiện nó với một XmlSerializer được tạo trên lớp cơ sở (không phải lớp con). – Ray

+0

[Serializable, XmlInclude (typeof (Sub))] trên lớp Cơ sở –

9

Bạn có thể đọc nút gốc tập tin XML và thay vì sử dụng một câu lệnh switch, bạn có thể viết mã của bạn như thế này -

Type yourType = Type.GetType("Your Type"); 
XmlSerializer xs = new XmlSerializer(yourType); 

Tôi không nghĩ rằng có bất kỳ cách nào khác hơn là đọc XML bởi vì nếu bạn không biết loại, bạn không thể làm gì cả.

0

Theo như tôi biết, không có cách nào đơn giản hơn để thực hiện việc này.

Cá nhân tôi thích một giải pháp chung chung hơn (vì tôi phải tuần tự hóa nhiều lớp khác nhau trong mã của mình): để giữ tên loại được tuần tự hóa cùng với giá trị.

Bạn có thể có một cái nhìn tại câu hỏi này cho một số chi tiết: Serialise to XML and include the type of the serialised object

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