方法 : 派生クラスのシリアル化を制御する

XmlElementAttribute 属性を使用して XML 要素の名前を変更することが、オブジェクトのシリアル化をカスタマイズする唯一の方法というわけではありません。既存のクラスからクラスを派生させ、この新しいクラスをシリアル化する方法を XmlSerializer インスタンスに指示することでも、XML ストリームをカスタマイズできます。

たとえば、Book クラスからクラスを派生させ、より多くのプロパティを持つ ExpandedBook クラスを作成できます。ただし、XmlSerializer に対して、シリアル化または逆シリアル化するときに、作成した派生型を受け入れるように指示する必要があります。そのためには、XmlElementAttribute インスタンスを作成し、そのType プロパティを該当する派生クラス型に設定します。XmlElementAttributeXmlAttributes インスタンスに追加します。次に、XmlAttributesXmlAttributeOverrides インスタンスに追加して、オーバーライドされる型、および派生クラスを受け入れるメンバの名前を指定します。これを次の例に示します。

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);
        }
    }
}

関連項目

タスク

方法 : オブジェクトをシリアル化する
方法 : XML ストリームの代替要素名を指定する

参照

XmlSerializer
XmlElementAttribute
XmlAttributes
XmlAttributeOverrides

その他の技術情報

XML シリアル化および SOAP シリアル化

Footer image

Copyright © 2007 by Microsoft Corporation.All rights reserved.