HOW TO:控制衍生類別的序列化
使用 XmlElementAttribute 屬性變更 XML 項目的名稱並非自訂物件序列化的唯一方法。您可從現有類別衍生以自訂化 XML 資料流並指示 XmlSerializer 執行個體如何序列化新類別。
例如,指定 Book
類別,您可從其中衍生並建立擁有更多屬性的 ExpandedBook
類別。然後,您必須指示 XmlSerializer 在序列化或還原序列化時,接受衍生型別。做法是建立 XmlElementAttribute 執行個體並設定其 Type 屬性為衍生類型型別。將 XmlElementAttribute 加入至 XmlAttributes 執行個體。然後加入 XmlAttributes 至 XmlAttributeOverrides 執行個體,指定要覆寫的型別以及接受衍生類別的成員名稱。這在下列範例中顯示。
範例
Public Class Orders
public Books() As Book
End Class
Public Class Book
public ISBN As String
End Class
Public Class ExpandedBook
Inherits Book
public NewEdition As Boolean
End Class
Public Class Run
Shared Sub Main()
Dim t As Run = New Run()
t.SerializeObject("Book.xml")
t.DeserializeObject("Book.xml")
End Sub
Public Sub SerializeObject(filename As String)
' Each overridden field, property, or type requires
' an XmlAttributes instance.
Dim attrs As XmlAttributes = New XmlAttributes()
' Creates an XmlElementAttribute instance to override the
' field that returns Book objects. The overridden field
' returns Expanded objects instead.
Dim attr As XmlElementAttribute = _
New XmlElementAttribute()
attr.ElementName = "NewBook"
attr.Type = GetType(ExpandedBook)
' Adds the element to the collection of elements.
attrs.XmlElements.Add(attr)
' Creates the XmlAttributeOverrides.
Dim attrOverrides As XmlAttributeOverrides = _
New XmlAttributeOverrides()
' Adds the type of the class that contains the overridden
' member, as well as the XmlAttributes instance to override it
' with, to the XmlAttributeOverrides instance.
attrOverrides.Add(GetType(Orders), "Books", attrs)
' Creates the XmlSerializer using the XmlAttributeOverrides.
Dim s As XmlSerializer = _
New XmlSerializer(GetType(Orders), attrOverrides)
' Writing the file requires a TextWriter instance.
Dim writer As TextWriter = New StreamWriter(filename)
' Creates the object to be serialized.
Dim myOrders As Orders = New Orders()
' Creates an object of the derived type.
Dim b As ExpandedBook = New ExpandedBook()
b.ISBN= "123456789"
b.NewEdition = True
myOrders.Books = New ExpandedBook(){b}
' Serializes the object.
s.Serialize(writer,myOrders)
writer.Close()
End Sub
Public Sub DeserializeObject(filename As String)
Dim attrOverrides As XmlAttributeOverrides = _
New XmlAttributeOverrides()
Dim attrs As XmlAttributes = New XmlAttributes()
' Creates an XmlElementAttribute to override the
' field that returns Book objects. The overridden field
' returns Expanded objects instead.
Dim attr As XmlElementAttribute = _
New XmlElementAttribute()
attr.ElementName = "NewBook"
attr.Type = GetType(ExpandedBook)
' Adds the XmlElementAttribute to the collection of objects.
attrs.XmlElements.Add(attr)
attrOverrides.Add(GetType(Orders), "Books", attrs)
' Creates the XmlSerializer using the XmlAttributeOverrides.
Dim s As XmlSerializer = _
New XmlSerializer(GetType(Orders), attrOverrides)
Dim fs As FileStream = New FileStream(filename, FileMode.Open)
Dim myOrders As Orders = CType( s.Deserialize(fs), Orders)
Console.WriteLine("ExpandedBook:")
' The difference between deserializing the overridden
' XML document and serializing it is this: To read the derived
' object values, you must declare an object of the derived type
' and cast the returned object to it.
Dim expanded As ExpandedBook
Dim b As Book
for each b in myOrders.Books
expanded = CType(b, ExpandedBook)
Console.WriteLine(expanded.ISBN)
Console.WriteLine(expanded.NewEdition)
Next
End Sub
End Class
public class Orders
{
public Book[] Books;
}
public class Book
{
public string ISBN;
}
public class ExpandedBook:Book
{
public bool NewEdition;
}
public class Run
{
public void SerializeObject(string filename)
{
// Each overridden field, property, or type requires
// an XmlAttributes instance.
XmlAttributes attrs = new XmlAttributes();
// Creates an XmlElementAttribute instance to override the
// field that returns Book objects. The overridden field
// returns Expanded objects instead.
XmlElementAttribute attr = new XmlElementAttribute();
attr.ElementName = "NewBook";
attr.Type = typeof(ExpandedBook);
// Adds the element to the collection of elements.
attrs.XmlElements.Add(attr);
// Creates the XmlAttributeOverrides instance.
XmlAttributeOverrides attrOverrides = new XmlAttributeOverrides();
// Adds the type of the class that contains the overridden
// member, as well as the XmlAttributes instance to override it
// with, to the XmlAttributeOverrides.
attrOverrides.Add(typeof(Orders), "Books", attrs);
// Creates the XmlSerializer using the XmlAttributeOverrides.
XmlSerializer s =
new XmlSerializer(typeof(Orders), attrOverrides);
// Writing the file requires a TextWriter instance.
TextWriter writer = new StreamWriter(filename);
// Creates the object to be serialized.
Orders myOrders = new Orders();
// Creates an object of the derived type.
ExpandedBook b = new ExpandedBook();
b.ISBN= "123456789";
b.NewEdition = true;
myOrders.Books = new ExpandedBook[]{b};
// Serializes the object.
s.Serialize(writer,myOrders);
writer.Close();
}
public void DeserializeObject(string filename)
{
XmlAttributeOverrides attrOverrides =
new XmlAttributeOverrides();
XmlAttributes attrs = new XmlAttributes();
// Creates an XmlElementAttribute to override the
// field that returns Book objects. The overridden field
// returns Expanded objects instead.
XmlElementAttribute attr = new XmlElementAttribute();
attr.ElementName = "NewBook";
attr.Type = typeof(ExpandedBook);
// Adds the XmlElementAttribute to the collection of objects.
attrs.XmlElements.Add(attr);
attrOverrides.Add(typeof(Orders), "Books", attrs);
// Creates the XmlSerializer using the XmlAttributeOverrides.
XmlSerializer s =
new XmlSerializer(typeof(Orders), attrOverrides);
FileStream fs = new FileStream(filename, FileMode.Open);
Orders myOrders = (Orders) s.Deserialize(fs);
Console.WriteLine("ExpandedBook:");
// The difference between deserializing the overridden
// XML document and serializing it is this: To read the derived
// object values, you must declare an object of the derived type
// and cast the returned object to it.
ExpandedBook expanded;
foreach(Book b in myOrders.Books)
{
expanded = (ExpandedBook)b;
Console.WriteLine(
expanded.ISBN + "\n" +
expanded.NewEdition);
}
}
}
另請參閱
工作
HOW TO:序列化物件
HOW TO:指定 XML 資料流的替代項目名稱
參考
XmlSerializer
XmlElementAttribute
XmlAttributes
XmlAttributeOverrides
其他資源
建置日期:2010-03-10