System.Xml.Serialization 命名 ...


.NET Framework 類別庫
XmlSerializer 類別

更新:2007 年 11 月

將物件序列化成為 XML 文件,以及從 XML 文件將物件還原序列化。XmlSerializer 可讓您控制如何將物件編碼為 XML。

命名空間:  System.Xml.Serialization
組件:  System.Xml (在 System.Xml.dll 中)

語法

Visual Basic (宣告)
Public Class XmlSerializer
Visual Basic (使用方式)
Dim instance As XmlSerializer
C#
public class XmlSerializer
Visual C++
public ref class XmlSerializer
J#
public class XmlSerializer
JScript
public class XmlSerializer
備註

XML 序列化 (Serialization) 是將物件公用屬性和欄位轉換為儲存或傳輸所用的序列格式 (此處即為 XML) 的程。還原序列化 (Deserialization) 是從 XML 輸出將物件重新建立成它的原始狀態。您可以將序列化視為在資料流或緩衝區中儲存物件狀態的方式。例如,ASP.NET 是使用 XmlSerializer 類別來編碼 XML Web Service 訊息。

您物件中的資料是用程式語言來描述的,該程式語言會建構如類別、欄位、屬性、基本型別 (Primitive Type)、陣列,甚至是以 XmlElementXmlAttribute 物件為格式的內嵌 XML。您可以選擇以屬性註解建立自己的類別,或使用 XML 結構描述定義工具 (Xsd.exe) 來產生依據現有 XML 結構描述定義 (XSD) 文件的類別。如果有 XML 結構描述,您可以執行 Xsd.exe 來產生類別集,這些類別集是結構描述的強型別 (Strongly Typed),而且在序列化時以屬性註解來符合結構描述。

為了在物件之間傳輸資料,XML 需要從程式語言建構至 XML 結構描述的對應,以及從 XML 結構描述至程式語言建構的對應。XmlSerializer 和相關工具 (如 Xsd.exe),在設計階段和執行階段都提供了連接這兩項技術的橋樑。在設計階段,請使用 Xsd.exe 從自訂類別產生 XML 結構描述文件 (.xsd),或從指定的結構描述產生類別。不論哪一種情況,類別都會加註自訂屬性,指示 XmlSerializer 如何在 XML 結構描述系統和 Common Language Runtime 之間對應。在執行階段,可以將類別的執行個體序列化成符合指定之結構描述的 XML 文件。同樣地,這些 XML 文件可以還原序列化成執行階段物件。請注意,XML 結構描述是選擇性的,在設計階段或執行階段並不需要。

控制產生的 XML

若要控制產生的 XML,您可以將一些特別的屬性套用至類別和成員。例如,若要指定不同的 XML 項目名稱,可將 XmlElementAttribute 套用至公用欄位或屬性,並且設定 ElementName 屬性。如需類似屬性的完整清單,請參閱 控制 XML 序列化的屬性。您也可以實作 IXmlSerializable 介面,以控制 XML 輸出。

如果產生的 XML 必須符合全球資訊網協會 (www.w3.org) 文件<Simple Object Access Protocol (SOAP) 1.1>的第 5 節,您必須使用 XmlTypeMapping 來建構 XmlSerializer。若要進一步控制編碼的 SOAP XML,請使用 控制編碼 SOAP 序列化的屬性 中所列的屬性。

使用 XmlSerializer,您可以利用強型別類別來運作,而且還保有 XML 的彈性。在強型別類別中使用 XmlElementXmlAttributeXmlNode 型別的欄位或屬性,可以直接將 XML 文件的部分讀取至 XML 物件中。

如果使用可延伸 XML 結構描述,您也可以使用 XmlAnyElementAttributeXmlAnyAttributeAttribute 屬性來序列化和還原序列化原始結構描述中找不到的項目和屬性。若要使用該物件,請將 XmlAnyElementAttribute 套用到傳回 XmlElement 物件陣列的欄位,或將 XmlAnyAttributeAttribute 套用到傳回 XmlAttribute 物件陣列的欄位。

如果屬性或欄位傳回複雜物件 (例如陣列或類別執行個體),XmlSerializer 會將它轉換為主要 XML 文件中的巢狀項目。例如,下列程式碼中的第一個類別,會傳回第二個類別的執行個體。

Visual Basic
Public Class MyClass
    Public MyObjectProperty As MyObject
End Class

Public Class MyObject
    Public ObjectName As String
End Class
C#
public class MyClass
{
    public MyObject MyObjectProperty;
}
public class MyObject
{
    public string ObjectName;
}

已序列化的 XML 輸出看起來會像這樣:

<MyClass>
  <MyObjectProperty>
  <ObjectName>My String</ObjectName>
  </MyObjectProperty>
</MyClass>

如果結構描述包含選擇性的項目 (minOccurs = '0'),或如果結構描述包含預設值,您就有兩種選擇。一個選項是使用 System.ComponentModel..::.DefaultValueAttribute,指定預設值,如下列程式碼所示。

Visual Basic
Public Class PurchaseOrder
    <System.ComponentModel.DefaultValueAttribute ("2002")> _
    Public Year As String
End Class
C#
public class PurchaseOrder
{
    [System.ComponentModel.DefaultValueAttribute ("2002")]
    public string Year;
}

另一種選擇是使用特別的模式以建立 XmlSerializer 可辨識的布林 (Boolean) 欄位,並套用 XmlIgnoreAttribute 至該欄位。以 propertyNameSpecified 的格式建立其模式。例如,如果有名為 "MyFirstName" 的欄位,您也會建立名為 "MyFirstNameSpecified" 的欄位,指示 XmlSerializer 是否要產生名為 "MyFirstName" 的 XML 項目。這在下列範例中顯示。

Visual Basic
Public Class OptionalOrder
    ' This field's value should not be serialized 
    ' if it is uninitialized.
    Public FirstOrder As String

    ' Use the XmlIgnoreAttribute to ignore the 
    ' special field named "FirstOrderSpecified".
    <System.Xml.Serialization.XmlIgnoreAttribute> _
    Public FirstOrderSpecified As Boolean
End Class
C#
public class OptionalOrder
{
    // This field should not be serialized 
    // if it is uninitialized.
    public string FirstOrder;

    // Use the XmlIgnoreAttribute to ignore the 
    // special field named "FirstOrderSpecified".
    [System.Xml.Serialization.XmlIgnoreAttribute]
    public bool FirstOrderSpecified;
}

覆寫預設的序列化

您也可以建立一個適當的屬性,並將其加入 XmlAttributes 類別的執行個體,藉以覆寫任何物件集及其欄位和屬性的序列化。使用這個方式覆寫序列化有兩個用途:第一,您可以控制並擴大 DLL 中物件的序列化 (即使您沒有該來源的存取權),第二,您可以建立一組可序列化類別,但以多種方式序列化物件。如需詳細資訊,請參閱 XmlAttributeOverrides 類別和 HOW TO:控制衍生類別的序列化

若要序列化物件,請呼叫 Serialize 方法。若要還原序列化物件,請呼叫 Deserialize 方法。

若要將 XML 命名空間加入至 XML 文件,請參閱 XmlSerializerNamespaces

注意事項:

XmlSerializer 會對實作 IEnumerableICollection 的類別特別處理。實作 IEnumerable 的類別必須實作只取單一參數的公用 Add 方法。Add 方法的參數必須和從 GetEnumerator 傳回的值的 Current 屬性所傳回的參數相同型別,或者是那個型別的基底其中之一。除了實作 IEnumerable 之外還實作 ICollection 的類別 (例如 CollectionBase) 必須具有公用的 Item 整數索引屬性 (C# 中的索引子),而且還必須具有公用的 Count 型別整數屬性。Add 方法的參數必須和 Item 屬性傳回的參數相同型別,或者該型別的基底其中之一。針對實作 ICollection 的類別,要序列化的值擷取自索引的 Item 屬性,而不是呼叫 GetEnumerator 進行擷取。

您必須具有寫入暫存目錄 (由 TEMP 環境變數定義) 的權限,才能還原序列化物件。

動態產生的組件

為了增加效能,XML 序列化基礎結構會動態產生組件,以序列化和還原序列化指定的型別。基礎結構會尋找並重新使用那些組件。只有在使用下列建構函式時,才會出現這個行為:

XmlSerializer..::.XmlSerializer(Type)

XmlSerializer..::.XmlSerializer(Type, String)

如果您使用任何其他建構函式,則會產生相同組件的多個版本且無法卸載,導致記憶體遺漏和效能不佳。最簡單的解決方案就是使用先前提及的兩個建構函式。否則,您必須在 Hashtable 中快取組件,如下列範例所示。

C#
Hashtable serializers = new Hashtable();

// Use the constructor that takes a type and XmlRootAttribute.
XmlSerializer s = new XmlSerializer(typeof(MyClass), myRoot);

// Implement a method named GenerateKey that creates unique keys 
// for each instance of the XmlSerializer. The code should take 
// into account all parameters passed to the XmlSerializer 
// constructor.
object key = GenerateKey(typeof(MyClass), myRoot);

// Check the local cache for a matching serializer.
XmlSerializer ser = (XmlSerializer)serializers[key];
if (ser == null) 
{
    ser = new XmlSerializer(typeof(MyClass), myRoot);
    // Cache the serializer.
    serializers[key] = ser;
}
else
{
    // Use the serializer to serialize, or deserialize.
}
Visual Basic
Dim serializers As New Hashtable()

' Use the constructor that takes a type and XmlRootAttribute.
Dim s As New XmlSerializer(GetType([MyClass]), myRoot)

' Implement a method named GenerateKey that creates unique keys 
' for each instance of the XmlSerializer. The code should take 
' into account all parameters passed to the XmlSerializer 
' constructor.
Dim key As Object = GenerateKey(GetType([MyClass]), myRoot)

' Check the local cache for a matching serializer.
Dim ser As XmlSerializer = CType(serializers(key), XmlSerializer)

If ser Is Nothing Then
    ser = New XmlSerializer(GetType([MyClass]), myRoot)
    ' Cache the serializer.
    serializers(key) = ser
Else 
    ' Use the serializer to serialize, or deserialize.
End If

ArrayList 和泛型清單的序列化

XmlSerializer 無法序列化或還原序列化下列項目:

序列化 Unsigned Long 的列舉型別

如果下列條件成立,就無法產生 XmlSerializer 以序列化列舉型別:列舉型別為 Unsigned Long (C# 中為 ulong),而且列舉型別包含值大於 9,223,372,036,854,775,807 的任何成員。例如,下列項目無法序列化。

public enum LargeNumbers: ulong
{
    a = 9223372036854775808
}
// At runtime, the following code will fail.
xmlSerializer mySerializer=new XmlSerializer(typeof(LargeNumbers));

以 Obsolete 屬性標示的物件不會再序列化

在 .NET Framework 3.5 中,XmlSerializer 類別不會再序列化標示為 [Obsolete] 的物件。

範例

下列範例會含有名稱為 PurchaseOrderTest 的兩個類別。該 PurchaseOrder 類別內含單次採購的相關資訊。Test 類別則包含了建立採購訂單以及讀取所建立之採購定單的方法。

Visual Basic
Imports System
Imports System.Xml
Imports System.Xml.Serialization
Imports System.IO
Imports Microsoft.VisualBasic


' The XmlRootAttribute allows you to set an alternate name
' (PurchaseOrder) of the XML element, the element namespace; by
' default, the XmlSerializer uses the class name. The attribute
' also allows you to set the XML namespace for the element.  Lastly,
' the attribute sets the IsNullable property, which specifies whether
' the xsi:null attribute appears if the class instance is set to
' a null reference. 
<XmlRootAttribute("PurchaseOrder", _
 Namespace := "http://www.cpandl.com", IsNullable := False)> _
Public Class PurchaseOrder

    Public ShipTo As Address
    Public OrderDate As String
    ' The XmlArrayAttribute changes the XML element name
    ' from the default of "OrderedItems" to "Items". 
    <XmlArrayAttribute("Items")> _
    Public OrderedItems() As OrderedItem
    Public SubTotal As Decimal
    Public ShipCost As Decimal
    Public TotalCost As Decimal
End Class 'PurchaseOrder


Public Class Address
    ' The XmlAttribute instructs the XmlSerializer to serialize the Name
    ' field as an XML attribute instead of an XML element (the default
    ' behavior). 
    <XmlAttribute()> _
    Public Name As String
    Public Line1 As String

    ' Setting the IsNullable property to false instructs the
    ' XmlSerializer that the XML attribute will not appear if
    ' the City field is set to a null reference. 
    <XmlElementAttribute(IsNullable := False)> _
    Public City As String
    Public State As String
    Public Zip As String
End Class 'Address


Public Class OrderedItem
    Public ItemName As String
    Public Description As String
    Public UnitPrice As Decimal
    Public Quantity As Integer
    Public LineTotal As Decimal


    ' Calculate is a custom method that calculates the price per item,
    ' and stores the value in a field. 
    Public Sub Calculate()
        LineTotal = UnitPrice * Quantity
    End Sub 'Calculate
End Class 'OrderedItem


Public Class Test

   Public Shared Sub Main()
      ' Read and write purchase orders.
      Dim t As New Test()
      t.CreatePO("po.xml")
      t.ReadPO("po.xml")
   End Sub 'Main

   Private Sub CreatePO(filename As String)
      ' Create an instance of the XmlSerializer class;
      ' specify the type of object to serialize.
      Dim serializer As New XmlSerializer(GetType(PurchaseOrder))
      Dim writer As New StreamWriter(filename)
      Dim po As New PurchaseOrder()

      ' Create an address to ship and bill to.
      Dim billAddress As New Address()
      billAddress.Name = "Teresa Atkinson"
      billAddress.Line1 = "1 Main St."
      billAddress.City = "AnyTown"
      billAddress.State = "WA"
      billAddress.Zip = "00000"
      ' Set ShipTo and BillTo to the same addressee.
      po.ShipTo = billAddress
      po.OrderDate = System.DateTime.Now.ToLongDateString()

      ' Create an OrderedItem object.
      Dim i1 As New OrderedItem()
      i1.ItemName = "Widget S"
      i1.Description = "Small widget"
      i1.UnitPrice = CDec(5.23)
      i1.Quantity = 3
      i1.Calculate()

      ' Insert the item into the array.
      Dim items(0) As OrderedItem
      items(0) = i1
      po.OrderedItems = items
      ' Calculate the total cost.
      Dim subTotal As New Decimal()
      Dim oi As OrderedItem
      For Each oi In  items
         subTotal += oi.LineTotal
      Next oi
      po.SubTotal = subTotal
      po.ShipCost = CDec(12.51)
      po.TotalCost = po.SubTotal + po.ShipCost
      ' Serialize the purchase order, and close the TextWriter.
      serializer.Serialize(writer, po)
      writer.Close()
   End Sub 'CreatePO

   Protected Sub ReadPO(filename As String)
      ' Create an instance of the XmlSerializer class;
      ' specify the type of object to be deserialized.
      Dim serializer As New XmlSerializer(GetType(PurchaseOrder))
      ' If the XML document has been altered with unknown
      ' nodes or attributes, handle them with the
      ' UnknownNode and UnknownAttribute events.
      AddHandler serializer.UnknownNode, AddressOf serializer_UnknownNode
      AddHandler serializer.UnknownAttribute, AddressOf serializer_UnknownAttribute

      ' A FileStream is needed to read the XML document.
      Dim fs As New FileStream(filename, FileMode.Open)
      ' Declare an object variable of the type to be deserialized.
      Dim po As PurchaseOrder
      ' Use the Deserialize method to restore the object's state with
      ' data from the XML document. 
      po = CType(serializer.Deserialize(fs), PurchaseOrder)
      ' Read the order date.
      Console.WriteLine(("OrderDate: " & po.OrderDate))

      ' Read the shipping address.
      Dim shipTo As Address = po.ShipTo
      ReadAddress(shipTo, "Ship To:")
      ' Read the list of ordered items.
      Dim items As OrderedItem() = po.OrderedItems
      Console.WriteLine("Items to be shipped:")
      Dim oi As OrderedItem
      For Each oi In  items
         Console.WriteLine((ControlChars.Tab & oi.ItemName & ControlChars.Tab & _
         oi.Description & ControlChars.Tab & oi.UnitPrice & ControlChars.Tab & _
         oi.Quantity & ControlChars.Tab & oi.LineTotal))
      Next oi
      ' Read the subtotal, shipping cost, and total cost.
      Console.WriteLine(( New String(ControlChars.Tab, 5) & _
      " Subtotal"  & ControlChars.Tab & po.SubTotal))
      Console.WriteLine(New String(ControlChars.Tab, 5) & _
      " Shipping" & ControlChars.Tab & po.ShipCost )
      Console.WriteLine( New String(ControlChars.Tab, 5) & _
      " Total" &  New String(ControlChars.Tab, 2) & po.TotalCost)
    End Sub 'ReadPO

    Protected Sub ReadAddress(a As Address, label As String)
      ' Read the fields of the Address object.
      Console.WriteLine(label)
      Console.WriteLine(ControlChars.Tab & a.Name)
      Console.WriteLine(ControlChars.Tab & a.Line1)
      Console.WriteLine(ControlChars.Tab & a.City)
      Console.WriteLine(ControlChars.Tab & a.State)
      Console.WriteLine(ControlChars.Tab & a.Zip)
      Console.WriteLine()
    End Sub 'ReadAddress

    Private Sub serializer_UnknownNode(sender As Object, e As XmlNodeEventArgs)
        Console.WriteLine(("Unknown Node:" & e.Name & ControlChars.Tab & e.Text))
    End Sub 'serializer_UnknownNode


    Private Sub serializer_UnknownAttribute(sender As Object, e As XmlAttributeEventArgs)
        Dim attr As System.Xml.XmlAttribute = e.Attr
        Console.WriteLine(("Unknown attribute " & attr.Name & "='" & attr.Value & "'"))
    End Sub 'serializer_UnknownAttribute
End Class 'Test
C#
using System;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

/* The XmlRootAttribute allows you to set an alternate name 
   (PurchaseOrder) of the XML element, the element namespace; by 
   default, the XmlSerializer uses the class name. The attribute 
   also allows you to set the XML namespace for the element.  Lastly,
   the attribute sets the IsNullable property, which specifies whether 
   the xsi:null attribute appears if the class instance is set to 
   a null reference. */
[XmlRootAttribute("PurchaseOrder", Namespace="http://www.cpandl.com", 
IsNullable = false)]
public class PurchaseOrder
{
   public Address ShipTo;
   public string OrderDate; 
   /* The XmlArrayAttribute changes the XML element name
    from the default of "OrderedItems" to "Items". */
   [XmlArrayAttribute("Items")]
   public OrderedItem[] OrderedItems;
   public decimal SubTotal;
   public decimal ShipCost;
   public decimal TotalCost;   
}

public class Address
{
   /* The XmlAttribute instructs the XmlSerializer to serialize the Name
      field as an XML attribute instead of an XML element (the default
      behavior). */
   [XmlAttribute]
   public string Name;
   public string Line1;

   /* Setting the IsNullable property to false instructs the 
      XmlSerializer that the XML attribute will not appear if 
      the City field is set to a null reference. */
   [XmlElementAttribute(IsNullable = false)]
   public string City;
   public string State;
   public string Zip;
}

public class OrderedItem
{
   public string ItemName;
   public string Description;
   public decimal UnitPrice;
   public int Quantity;
   public decimal LineTotal;

   /* Calculate is a custom method that calculates the price per item,
      and stores the value in a field. */
   public void Calculate()
   {
      LineTotal = UnitPrice * Quantity;
   }
}

public class Test
{
   public static void Main()
   {
      // Read and write purchase orders.
      Test t = new Test();
      t.CreatePO("po.xml");
      t.ReadPO("po.xml");
   }

   private void CreatePO(string filename)
   {
      // Create an instance of the XmlSerializer class;
      // specify the type of object to serialize.
      XmlSerializer serializer = 
      new XmlSerializer(typeof(PurchaseOrder));
      TextWriter writer = new StreamWriter(filename);
      PurchaseOrder po=new PurchaseOrder();

      // Create an address to ship and bill to.
      Address billAddress = new Address();
      billAddress.Name = "Teresa Atkinson";
      billAddress.Line1 = "1 Main St.";
      billAddress.City = "AnyTown";
      billAddress.State = "WA";
      billAddress.Zip = "00000";
      // Set ShipTo and BillTo to the same addressee.
      po.ShipTo = billAddress;
      po.OrderDate = System.DateTime.Now.ToLongDateString();

      // Create an OrderedItem object.
      OrderedItem i1 = new OrderedItem();
      i1.ItemName = "Widget S";
      i1.Description = "Small widget";
      i1.UnitPrice = (decimal) 5.23;
      i1.Quantity = 3;
      i1.Calculate();

      // Insert the item into the array.
      OrderedItem [] items = {i1};
      po.OrderedItems = items;
      // Calculate the total cost.
      decimal subTotal = new decimal();
      foreach(OrderedItem oi in items)
      {
         subTotal += oi.LineTotal;
      }
      po.SubTotal = subTotal;
      po.ShipCost = (decimal) 12.51; 
      po.TotalCost = po.SubTotal + po.ShipCost; 
      // Serialize the purchase order, and close the TextWriter.
      serializer.Serialize(writer, po);
      writer.Close();
   }

   protected void ReadPO(string filename)
   {
      // Create an instance of the XmlSerializer class;
      // specify the type of object to be deserialized.
      XmlSerializer serializer = new XmlSerializer(typeof(PurchaseOrder));
      /* If the XML document has been altered with unknown 
      nodes or attributes, handle them with the 
      UnknownNode and UnknownAttribute events.*/
      serializer.UnknownNode+= new 
      XmlNodeEventHandler(serializer_UnknownNode);
      serializer.UnknownAttribute+= new 
      XmlAttributeEventHandler(serializer_UnknownAttribute);

      // A FileStream is needed to read the XML document.
      FileStream fs = new FileStream(filename, FileMode.Open);
      // Declare an object variable of the type to be deserialized.
      PurchaseOrder po;
      /* Use the Deserialize method to restore the object's state with
      data from the XML document. */
      po = (PurchaseOrder) serializer.Deserialize(fs);
      // Read the order date.
      Console.WriteLine ("OrderDate: " + po.OrderDate);

      // Read the shipping address.
      Address shipTo = po.ShipTo;
      ReadAddress(shipTo, "Ship To:");
      // Read the list of ordered items.
      OrderedItem [] items = po.OrderedItems;
      Console.WriteLine("Items to be shipped:");
      foreach(OrderedItem oi in items)
      {
         Console.WriteLine("\t"+
         oi.ItemName + "\t" + 
         oi.Description + "\t" +
         oi.UnitPrice + "\t" +
         oi.Quantity + "\t" +
         oi.LineTotal);
      }
      // Read the subtotal, shipping cost, and total cost.
      Console.WriteLine("\t\t\t\t\t Subtotal\t" + po.SubTotal);
      Console.WriteLine("\t\t\t\t\t Shipping\t" + po.ShipCost); 
      Console.WriteLine("\t\t\t\t\t Total\t\t" + po.TotalCost);
   }

   protected void ReadAddress(Address a, string label)
   {
      // Read the fields of the Address object.
      Console.WriteLine(label);
      Console.WriteLine("\t"+ a.Name );
      Console.WriteLine("\t" + a.Line1);
      Console.WriteLine("\t" + a.City);
      Console.WriteLine("\t" + a.State);
      Console.WriteLine("\t" + a.Zip );
      Console.WriteLine();
   }

   private void serializer_UnknownNode
   (object sender, XmlNodeEventArgs e)
   {
      Console.WriteLine("Unknown Node:" +   e.Name + "\t" + e.Text);
   }

   private void serializer_UnknownAttribute
   (object sender, XmlAttributeEventArgs e)
   {
      System.Xml.XmlAttribute attr = e.Attr;
      Console.WriteLine("Unknown attribute " + 
      attr.Name + "='" + attr.Value + "'");
   }
}
Visual C++
#using <System.Xml.dll>
#using <System.dll>

using namespace System;
using namespace System::Xml;
using namespace System::Xml::Serialization;
using namespace System::IO;
ref class Address;
ref class OrderedItem;

/* The XmlRootAttribute allows you to set an alternate name 
   (PurchaseOrder) of the XML element, the element namespace; by 
   default, the XmlSerializer uses the class name. The attribute 
   also allows you to set the XML namespace for the element.  Lastly,
   the attribute sets the IsNullable property, which specifies whether 
   the xsi:null attribute appears if the class instance is set to 
   a null reference. */

[XmlRootAttribute("PurchaseOrder",Namespace="http://www.cpandl.com",
IsNullable=false)]
public ref class PurchaseOrder
{
public:
   Address^ ShipTo;
   String^ OrderDate;

   /* The XmlArrayAttribute changes the XML element name
       from the default of "OrderedItems" to "Items". */

   [XmlArrayAttribute("Items")]
   array<OrderedItem^>^OrderedItems;
   Decimal SubTotal;
   Decimal ShipCost;
   Decimal TotalCost;
};

public ref class Address
{
public:

   /* The XmlAttribute instructs the XmlSerializer to serialize the Name
         field as an XML attribute instead of an XML element (the default
         behavior). */

   [XmlAttributeAttribute]
   String^ Name;
   String^ Line1;

   /* Setting the IsNullable property to false instructs the 
         XmlSerializer that the XML attribute will not appear if 
         the City field is set to a null reference. */

   [XmlElementAttribute(IsNullable=false)]
   String^ City;
   String^ State;
   String^ Zip;
};

public ref class OrderedItem
{
public:
   String^ ItemName;
   String^ Description;
   Decimal UnitPrice;
   int Quantity;
   Decimal LineTotal;

   /* Calculate is a custom method that calculates the price per item,
         and stores the value in a field. */
   void Calculate()
   {
      LineTotal = UnitPrice * Quantity;
   }

};

public ref class Test
{
public:
   static void main()
   {
      // Read and write purchase orders.
      Test^ t = gcnew Test;
      t->CreatePO( "po.xml" );
      t->ReadPO( "po.xml" );
   }

private:
   void CreatePO( String^ filename )
   {
      // Create an instance of the XmlSerializer class;
      // specify the type of object to serialize.
      XmlSerializer^ serializer = gcnew XmlSerializer( PurchaseOrder::typeid );
      TextWriter^ writer = gcnew StreamWriter( filename );
      PurchaseOrder^ po = gcnew PurchaseOrder;

      // Create an address to ship and bill to.
      Address^ billAddress = gcnew Address;
      billAddress->Name = "Teresa Atkinson";
      billAddress->Line1 = "1 Main St.";
      billAddress->City = "AnyTown";
      billAddress->State = "WA";
      billAddress->Zip = "00000";

      // Set ShipTo and BillTo to the same addressee.
      po->ShipTo = billAddress;
      po->OrderDate = System::DateTime::Now.ToLongDateString();

      // Create an OrderedItem object.
      OrderedItem^ i1 = gcnew OrderedItem;
      i1->ItemName = "Widget S";
      i1->Description = "Small widget";
      i1->UnitPrice = (Decimal)5.23;
      i1->Quantity = 3;
      i1->Calculate();

      // Insert the item into the array.
      array<OrderedItem^>^items = {i1};
      po->OrderedItems = items;

      // Calculate the total cost.
      Decimal subTotal = Decimal(0);
      System::Collections::IEnumerator^ myEnum = items->GetEnumerator();
      while ( myEnum->MoveNext() )
      {
         OrderedItem^ oi = safe_cast<OrderedItem^>(myEnum->Current);
         subTotal = subTotal + oi->LineTotal;
      }

      po->SubTotal = subTotal;
      po->ShipCost = (Decimal)12.51;
      po->TotalCost = po->SubTotal + po->ShipCost;

      // Serialize the purchase order, and close the TextWriter.
      serializer->Serialize( writer, po );
      writer->Close();
   }

protected:
   void ReadPO( String^ filename )
   {
      // Create an instance of the XmlSerializer class;
      // specify the type of object to be deserialized.
      XmlSerializer^ serializer = gcnew XmlSerializer( PurchaseOrder::typeid );

      /* If the XML document has been altered with unknown 
            nodes or attributes, handle them with the 
            UnknownNode and UnknownAttribute events.*/
      serializer->UnknownNode += gcnew XmlNodeEventHandler( this, &Test::serializer_UnknownNode );
      serializer->UnknownAttribute += gcnew XmlAttributeEventHandler( this, &Test::serializer_UnknownAttribute );

      // A FileStream is needed to read the XML document.
      FileStream^ fs = gcnew FileStream( filename,FileMode::Open );

      // Declare an object variable of the type to be deserialized.
      PurchaseOrder^ po;

      /* Use the Deserialize method to restore the object's state with
            data from the XML document. */
      po = dynamic_cast<PurchaseOrder^>(serializer->Deserialize( fs ));

      // Read the order date.
      Console::WriteLine( "OrderDate: {0}", po->OrderDate );

      // Read the shipping address.
      Address^ shipTo = po->ShipTo;
      ReadAddress( shipTo, "Ship To:" );

      // Read the list of ordered items.
      array<OrderedItem^>^items = po->OrderedItems;
      Console::WriteLine( "Items to be shipped:" );
      System::Collections::IEnumerator^ myEnum1 = items->GetEnumerator();
      while ( myEnum1->MoveNext() )
      {
         OrderedItem^ oi = safe_cast<OrderedItem^>(myEnum1->Current);
         Console::WriteLine( "\t{0}\t{1}\t{2}\t{3}\t{4}", oi->ItemName, oi->Description, oi->UnitPrice, oi->Quantity, oi->LineTotal );
      }

      Console::WriteLine( "\t\t\t\t\t Subtotal\t{0}", po->SubTotal );
      Console::WriteLine( "\t\t\t\t\t Shipping\t{0}", po->ShipCost );
      Console::WriteLine( "\t\t\t\t\t Total\t\t{0}", po->TotalCost );
   }

   void ReadAddress( Address^ a, String^ label )
   {
      // Read the fields of the Address object.
      Console::WriteLine( label );
      Console::WriteLine( "\t{0}", a->Name );
      Console::WriteLine( "\t{0}", a->Line1 );
      Console::WriteLine( "\t{0}", a->City );
      Console::WriteLine( "\t{0}", a->State );
      Console::WriteLine( "\t{0}", a->Zip );
      Console::WriteLine();
   }

private:
   void serializer_UnknownNode( Object^ /*sender*/, XmlNodeEventArgs^ e )
   {
      Console::WriteLine( "Unknown Node:{0}\t{1}", e->Name, e->Text );
   }

   void serializer_UnknownAttribute( Object^ /*sender*/, XmlAttributeEventArgs^ e )
   {
      System::Xml::XmlAttribute^ attr = e->Attr;
      Console::WriteLine( "Unknown attribute {0}='{1}'", attr->Name, attr->Value );
   }
};

int main()
{
   Test::main();
}
J#
import System.*;
import System.Xml.*;
import System.Xml.Serialization.*;
import System.IO.*;

/* The XmlRootAttribute allows you to set an alternate name 
   (PurchaseOrder) of the XML element, the element namespace; by 
   default, the XmlSerializer uses the class name. The attribute 
   also allows you to set the XML namespace for the element.  Lastly,
   the attribute sets the IsNullable property, which specifies whether 
   the xsi:null attribute appears if the class instance is set to 
   a null reference. */
/** @attribute XmlRootAttribute("PurchaseOrder",
    Namespace = "http://www.cpandl.com", IsNullable = false)
 */
public class PurchaseOrder
{
    public Address shipTo;
    public String orderDate;
    /* The XmlArrayAttribute changes the XML element name
       from the default of "OrderedItems" to "Items". */
    /** @attribute XmlArrayAttribute("Items")
     */
    public OrderedItem orderedItems[];
    public System.Decimal subTotal;
    public System.Decimal shipCost;
    public System.Decimal totalCost;
} //PurchaseOrder

public class Address
{
    /* The XmlAttribute instructs the XmlSerializer to serialize the Name
       field as an XML attribute instead of an XML element (the default
       behavior). */
    /** @attribute XmlAttribute()
     */
    public String name;
    public String line1;

    /* Setting the IsNullable property to false instructs the 
       XmlSerializer that the XML attribute will not appear if 
       the City field is set to a null reference. */
    /** @attribute XmlElementAttribute(IsNullable = false)
     */
    public String city;
    public String state;
    public String zip;
} //Address

public class OrderedItem
{
    public String itemName;
    public String description;
    public System.Decimal unitPrice;
    public int quantity;
    public System.Decimal lineTotal;

    /* Calculate is a custom method that calculates the price per item,
       and stores the value in a field. */
    public void Calculate()
    {
        lineTotal = Decimal.Multiply(unitPrice, Convert.ToDecimal(quantity));
    } //Calculate
} //OrderedItem

public class Test
{
    public static void main(String[] args)
    {
        // Read and write purchase orders.
        Test t = new Test();
        t.CreatePO("po.xml");
        t.ReadPO("po.xml");
    } //main

    private void CreatePO(String fileName)
    {
        // Create an instance of the XmlSerializer class;
        // specify the type of object to serialize.
        XmlSerializer serializer =
            new XmlSerializer(PurchaseOrder.class.ToType());
        TextWriter writer = new StreamWriter(fileName);
        PurchaseOrder po = new PurchaseOrder();

        // Create an address to ship and bill to.
        Address billAddress = new Address();
        billAddress.name = "Teresa Atkinson";
        billAddress.line1 = "1 Main St.";
        billAddress.city = "AnyTown";
        billAddress.state = "WA";
        billAddress.zip = "00000";

        // Set ShipTo and BillTo to the same addressee.
        po.shipTo = billAddress;
        po.orderDate = System.DateTime.get_Now().ToLongDateString();

        // Create an OrderedItem object.
        OrderedItem i1 = new OrderedItem();
        i1.itemName = "Widget S";
        i1.description = "Small widget";
        i1.unitPrice = Convert.ToDecimal(5.23);
        i1.quantity = 3;
        i1.Calculate();

        // Insert the item into the array.
        OrderedItem items[] = { i1 };
        po.orderedItems = items;

        // Calculate the total cost.
        System.Decimal subTotal = new System.Decimal();
        for (int iCtr = 0; iCtr < items.length; iCtr++) {
            OrderedItem oi = items[iCtr];
            subTotal = Decimal.Add(subTotal, oi.lineTotal);
        }

        po.subTotal = subTotal;
        po.shipCost = Convert.ToDecimal(12.51);
        po.totalCost = Decimal.Add(po.subTotal, po.shipCost);

        // Serialize the purchase order, and close the TextWriter.
        serializer.Serialize(writer, po);
        writer.Close();
    } //CreatePO

    protected void ReadPO(String fileName)
    {
        // Create an instance of the XmlSerializer class;
        // specify the type of object to be deserialized.
        XmlSerializer serializer =
            new XmlSerializer(PurchaseOrder.class.ToType());
        /* If the XML document has been altered with unknown 
           nodes or attributes, handle them with the 
           UnknownNode and UnknownAttribute events.*/
        serializer.add_UnknownNode(
            new XmlNodeEventHandler(Serializer_UnknownNode));
        serializer.add_UnknownAttribute(
            new XmlAttributeEventHandler(Serializer_UnknownAttribute));

        // A FileStream is needed to read the XML document.
        FileStream fs = new FileStream(fileName, FileMode.Open);

        // Declare an object variable of the type to be deserialized.
        PurchaseOrder po;

        /* Use the Deserialize method to restore the object's state with
           data from the XML document. */
        po = (PurchaseOrder)serializer.Deserialize(fs);

        // Read the order date.
        Console.WriteLine("OrderDate: " + po.orderDate);

        // Read the shipping address.
        Address shipTo = po.shipTo;
        ReadAddress(shipTo, "Ship To:");

        // Read the list of ordered items.
        OrderedItem items[] = po.orderedItems;
        Console.WriteLine("Items to be shipped:");
        for (int iCtr = 0; iCtr < items.length; iCtr++) {
            OrderedItem oi = items[iCtr];
            Console.WriteLine("\t" + oi.itemName + "\t"
                + oi.description + "\t" + oi.unitPrice + "\t"
                + oi.quantity + "\t" + oi.lineTotal);
        }
        // Read the subtotal, shipping cost, and total cost.
        Console.WriteLine("\t\t\t\t\t Subtotal\t" + po.subTotal);
        Console.WriteLine("\t\t\t\t\t Shipping\t" + po.shipCost);
        Console.WriteLine("\t\t\t\t\t Total\t\t" + po.totalCost);
    } //ReadPO

    protected void ReadAddress(Address a, String label)
    {
        // Read the fields of the Address object.
        Console.WriteLine(label);
        Console.WriteLine("\t" + a.name);
        Console.WriteLine("\t" + a.line1);
        Console.WriteLine("\t" + a.city);
        Console.WriteLine("\t" + a.state);
        Console.WriteLine("\t" + a.zip);
        Console.WriteLine();
    } //ReadAddress

    private void Serializer_UnknownNode(Object sender, XmlNodeEventArgs e)
    {
        Console.WriteLine("Unknown Node:" + e.get_Name() + "\t" + e.get_Text());
    } //Serializer_UnknownNode

    private void Serializer_UnknownAttribute(Object sender,
        XmlAttributeEventArgs e)
    {
        System.Xml.XmlAttribute attr = e.get_Attr();
        Console.WriteLine("Unknown attribute " + attr.get_Name() + "='"
            + attr.get_Value() + "'");
    } //Serializer_UnknownAttribute
} //Test
繼承階層架構

System..::.Object
  System.Xml.Serialization..::.XmlSerializer
執行緒安全

此型別具備執行緒安全。

平台

Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98, Windows CE, Windows Mobile for Smartphone, Windows Mobile for Pocket PC, Xbox 360

.NET Framework 和 .NET Compact Framework 並不支援各種平台的所有版本。如需支援平台版本的相關資訊,請參閱.NET Framework 系統需求

版本資訊

.NET Framework

支援版本:3.5、3.0、2.0、1.1、1.0

.NET Compact Framework

支援版本:3.5、2.0

XNA Framework

支援版本:2.0、1.0
請參閱

參考

XmlSerializer

其他資源

標記 :


Page view tracker