Substitution de la sérialisation XML
À l'aide de XmlSerializer, vous pouvez générer plusieurs flux XML avec le même ensemble de classes. Vous pouvez vouloir effectuer cette opération car deux services Web XML différents nécessitent les mêmes informations de base, à quelques différences près. Par exemple, imaginez deux services Web XML qui traitent des commandes de livres et nécessitent par conséquent des numéros ISBN. Un service utilise la balise <ISBN>, l'autre service utilise la balise <BookID>. Vous avez une classe nommée Book
qui contient un champ nommé ISBN
. Lorsqu'une instance de la classe Book
est sérialisée, elle utilisera, par défaut, le nom de membre (ISBN) comme le nom de l'élément balise. C'est ce qui est prévu pour le premier service Web XML. Cependant, pour envoyer le flux XML au deuxième service Web XML, vous devez substituer la sérialisation pour que le nom d'élément de la balise soit BookID
.
Pour créer un flux XML avec un autre nom d'élément
- Créez une instance de la classe XmlElementAttribute.
- Attribuez la valeur « BookID » à ElementName de XmlElementAttribute.
- Créez une instance de la classe XmlAttributes.
- Ajoutez l'objet XmlElementAttribute à la collection accessible par la propriété XmlElements de XmlAttributes.
- Créez une instance de la classe XmlAttributeOverrides.
- Ajoutez XmlAttributes à XmlAttributeOverrides, en passant le type de l'objet à substituer et le nom du membre qui est substitué.
- Créez une instance de la classe XmlSerializer à l'aide de XmlAttributeOverrides.
- Créez une instance de la classe
Book
, et sérialisez ou désérialisez cette classe.
L'exemple suivant illustre ce processus de sérialisation.
Public Class SerializeOverride()
' Creates an XmlElementAttribute with the alternate name.
Dim myElementAttribute As XmlElementAttribute = _
New XmlElementAttribute()
myElementAttribute.ElementName = "BookID"
Dim myAttributes As XmlAttributes = New XmlAttributes()
myAttributes.XmlElements.Add(myElementAttribute)
Dim myOverrides As XmlAttributeOverrides = New XmlAttributeOverrides()
myOverrides.Add(typeof(Book), "ISBN", myAttributes)
Dim mySerializer As XmlSerializer = _
New XmlSerializer(GetType(Book), myOverrides)
Dim b As Book = New Book()
b.ISBN = "123456789"
' Creates a StreamWriter to write the XML stream to.
Dim writer As StreamWriter = New StreamWriter("Book.xml")
mySerializer.Serialize(writer, b);
End Class
[C#]
public class SerializeOverride()
{
// Creates an XmlElementAttribute with the alternate name.
XmlElementAttribute myElementAttribute = new XmlElementAttribute();
myElementAttribute.ElementName = "BookID";
XmlAttributes myAttributes = new XmlAttributes();
myAttributes.XmlElements.Add(myElementAttribute);
XmlAttributeOverrides myOverrides = new XmlAttributeOverrides();
myOverrides.Add(typeof(Book), "ISBN", myAttributes);
XmlSerializer mySerializer =
new XmlSerializer(typeof(Book), myOverrides)
Book b = new Book();
b.ISBN = "123456789"
// Creates a StreamWriter to write the XML stream to.
StreamWriter writer = new StreamWriter("Book.xml");
mySerializer.Serialize(writer, b);
}
Le flux XML peut ressembler à ce qui suit.
<Book>
<BookID>123456789</BookID>
</Book>
Substitution de classes
Vous pouvez également créer un autre flux XML en dérivant à partir de classes existantes et en ordonnant à XmlSerializer de sérialiser ces classes. Par exemple, à partir de la classe Book
ci-dessus, vous pouvez dériver et créer une classe ExpandedBook
qui possède quelques propriétés supplémentaires. Cependant, vous devez ordonner à XmlSerializer d'accepter le type dérivé lors de la sérialisation ou désérialisation. Pour ce faire, vous pouvez créer un XmlElementAttribute et attribuer la valeur du type classe dérivé à sa propriété Type. Ajoutez XmlElementAttribute à XmlAttributes. Puis, ajoutez XmlAttributes à XmlAttributeOverrides, en spécifiant le type substitué et le nom du membre qui accepte la classe dérivée. Cela est illustré par l'exemple suivant.
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.
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 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, and the XmlAttributes to override it with, to the
' XmlAttributeOverrides.
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.
Dim writer As TextWriter = New StreamWriter(filename)
' Creates the object that will 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
[C#]
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.
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 element to the collection of elements.
attrs.XmlElements.Add(attr);
// Creates the XmlAttributeOverrides.
XmlAttributeOverrides attrOverrides = new XmlAttributeOverrides();
// Adds the type of the class that contains the overridden
// member, and the XmlAttributes 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.
TextWriter writer = new StreamWriter(filename);
// Creates the object that will 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);
}
}
}
Voir aussi
Sérialisation XML et SOAP | XmlSerializer | XmlElementAttribute XmlAttributes | XmlAttributeOverrides