Cómo: Controlar la serialización de clases derivadas
Utilizar el atributo XmlElementAttribute para cambiar el nombre de un elemento XML no es la única manera de personalizar la serialización de objeto. También puede personalizar la secuencia XML derivando de una clase existente e indicando a la instancia XmlSerializer cómo serializar la nueva clase.
Por ejemplo, dada una clase Book
, puede derivar de él y crear una clase ExpandedBook
que tiene más propiedades. Sin embargo, debe indicarle XmlSerializer que acepte el tipo derivado al serializar o deserializar. Esto se puede hacer creando una instancia XmlElementAttribute y estableciendo su propiedad Type en el tipo de clase derivada. Agregue XmlElementAttribute a la instancia XmlAttributes . A continuación agrega XmlAttributes a una instancia XmlAttributeOverrides, especificando el tipo que se invalida y el nombre del miembro que acepta la clase derivada. El ejemplo siguiente muestra esta opción.
Ejemplo
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);
}
}
}
Vea también
Tareas
Cómo: Serializar un objeto
Cómo: Especificar un nombre de elemento alternativo para una secuencia XML
Referencia
XmlSerializer
XmlElementAttribute
XmlAttributes
XmlAttributeOverrides
Otros recursos
Fecha de compilación: 2010-03-10