共用方式為


覆寫 XML 序列化

藉由使用 XmlSerializer,您可使用同樣一組類別來產生一個以上的 XML 資料流。在兩個不同 XML Web Service 需要相同的基本資訊而差異極小的情況下,您可能會要這麼做。例如,假設現在有兩個處理書籍訂單的 Web 服務,因此兩者都需要 ISBN 編號。一服務使用 <ISBN> 標記 (Tag),而另一服務使用 <BookID> 標記。另外還有個包含 ISBN 欄位的 Book 類別。當序列化 Book 類別的執行個體時,它會依預設使用成員名稱 (ISBN) 當作標記項目名稱。對第一個 XML Web Service 來說,這麼做是意料之中的。不過若要將 XML 資料流傳送至第二個 Web 服務,您必須覆寫序列化來讓標記的項目名稱成為 BookID

若要使用其他項目名稱建立 XML 資料流

  1. 建立 XmlElementAttribute 類別的執行個體。
  2. XmlElementAttributeElementName 設定為「BookID」。
  3. 建立 XmlAttributes 類別的執行個體。
  4. XmlElementAttribute 物件加入透過 XmlAttributesXmlElements 屬性存取的集合。
  5. 建立 XmlAttributeOverrides 類別的執行個體。
  6. XmlAttributes 加入 XmlAttributeOverrides,傳遞要覆寫的物件型別和被覆寫的成員名稱。
  7. 使用 XmlAttributeOverrides 建立 XmlSerializer 類別的執行個體。
  8. 建立 Book 類別的執行個體,接著序列化或還原序列化它。

下列範例示範這個序列化處理序。

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

XML 資料流可能像這樣。

<Book>
    <BookID>123456789</BookID>
</Book>

覆寫類別

您也可從現有類別衍生並指示 XmlSerializer 序列化這些類別來建立其他 XML 資料流。例如,就先前範例中的 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. 
        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);
        }
    }
}

請參閱

XML 和 SOAP 序列化 | XmlSerializer | XmlElementAttribute | XmlAttributes | XmlAttributeOverrides