다음을 통해 공유


XmlSerializer 클래스

XML 문서 간에 개체를 serialize 및 deserialize합니다. XmlSerializer를 사용하면 개체가 XML로 인코딩되는 방식을 제어할 수 있습니다.

네임스페이스: System.Xml.Serialization
어셈블리: System.Xml(system.xml.dll)

구문

‘선언
Public Class XmlSerializer
‘사용 방법
Dim instance As XmlSerializer
public class XmlSerializer
public ref class XmlSerializer
public class XmlSerializer
public class XmlSerializer

설명

XML serialization은 개체의 공용 속성 및 필드를 저장 또는 전송을 위해 직렬 형식(이 경우 XML)으로 변환하는 프로세스입니다. Deserialization은 XML 출력에서 개체를 원래 상태로 다시 만드는 프로세스입니다. 따라서 serialization은 개체의 상태를 스트림 또는 버퍼에 저장하는 방식 중 하나라고 할 수 있습니다. 예를 들어, ASP.NET은 XmlSerializer 클래스를 사용하여 XML Web services 메시지를 인코딩합니다.

개체 내의 데이터는 클래스, 필드, 속성, 기본 형식, 배열 및 XmlElement 또는 XmlAttribute 개체 형식으로 포함된 XML과 같은 프로그래밍 언어 구조를 통하여 설명됩니다. 특성으로 주석이 첨부된 클래스를 직접 만들거나, XML 스키마 정의 도구(Xsd.exe)를 사용하여 기존 XSD(XML 스키마 정의) 문서를 기반으로 클래스를 생성할 수도 있습니다. XML 스키마가 있는 경우, Xsd.exe를 실행하면 스키마로 강력하게 형식화되고 serialize할 때 스키마에 맞도록 특성이 주석으로 첨부된 클래스 집합을 생성할 수 있습니다.

개체와 XML 간의 데이터 전송을 위해서는 프로그래밍 언어 구문에서 XML 스키마로의 매핑 및 그 반대로의 매핑도 필요합니다. XmlSerializer 및 Xsd.exe와 같은 관련 도구는 디자인 타임 및 런타임에 이러한 두 기술을 적절히 연결해 주는 기능을 합니다. 디자인 타임에는 Xsd.exe를 사용하여 사용자 지정 클래스에서 XML 스키마 문서(.xsd)를 생성하거나 지정된 스키마에서 클래스를 생성합니다. 두 경우 모두, XML 스키마 시스템과 공용 언어 런타임 간에 매핑하는 방법을 XmlSerializer에 지시하기 위해 사용자 지정 특성이 주석으로 첨부됩니다. 런타임에는 지정된 스키마를 따르는 XML 문서로 클래스의 인스턴스를 serialize할 수 있고 이러한 XML 문서를 런타임 개체로 deserialize할 수도 있습니다. XML 스키마는 선택적 요소이며 디자인 타임 또는 런타임에 반드시 필요한 것은 아닙니다.

생성된 XML 제어

클래스 및 멤버에 특수한 특성을 적용하면 생성된 XML을 제어할 수 있습니다. 예를 들어, 다른 XML 요소 이름을 지정하려면 공용 필드나 속성에 XmlElementAttribute를 적용하고 ElementName 속성을 설정합니다. 유사한 특성에 대한 전체 목록은 XML Serialization을 제어하는 특성을 참조하십시오. IXmlSerializable 인터페이스를 구현하여 XML 출력을 제어할 수도 있습니다.

생성된 XML이 World Wide Web 컨소시엄(www.w3.org) 문서의 5단원, "SOAP(Simple Object Access Protocol) 1.1"을 따르도록 하려면 XmlTypeMapping으로 XmlSerializer를 구성해야 합니다. 인코딩된 SOAP Serialization을 제어하는 특성에 나열된 특성을 사용하면 인코딩된 SOAP XML을 여러 가지 방법으로 제어할 수 있습니다.

XmlSerializer를 사용하면 강력하게 형식화된 클래스로 작업하면서 XML의 융통성을 계속 활용할 수 있습니다. 강력하게 형식화된 클래스에서 XmlElement, XmlAttribute 또는 XmlNode 형식의 필드나 속성을 사용하면 XML 문서의 일부를 XML 개체로 직접 읽어올 수 있습니다.

확장 가능 XML 스키마를 사용할 경우, XmlAnyElementAttributeXmlAnyAttributeAttribute와 같은 특성을 사용하면 원래 스키마에 없는 요소나 특성을 serialize하거나 deserialize할 수 있습니다. 개체를 사용하려면 XmlElement 개체의 배열을 반환하는 필드에 XmlAnyElementAttribute를 적용하거나 XmlAttribute 개체의 배열을 반환하는 필드에 XmlAnyAttributeAttribute를 적용합니다.

속성 또는 필드가 복잡한 개체(예: 배열 또는 클래스 인스턴스)를 반환하는 경우 XmlSerializer는 그 개체를 주 XML 문서 내의 중첩된 요소로 변환합니다. 예를 들어, 다음 코드의 첫째 클래스는 둘째 클래스의 인스턴스를 반환합니다.

Public Class MyClass
    Public MyObjectProperty As MyObject
End Class

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

serialize된 XML은 다음과 같이 출력됩니다.

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

스키마가 선택적인 요소(minOccurs = '0')를 포함하거나 기본값을 포함할 경우 사용할 수 있는 두 가지 옵션이 있습니다. 한 가지 옵션은 다음 코드에서와 같이 System.ComponentModel.DefaultValueAttribute를 사용하여 기본값을 지정하는 것입니다.

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

또 다른 옵션은 특수 패턴을 사용하여 XmlSerializer에서 인식하는 부울 필드를 만든 후 해당 필드에 XmlIgnoreAttribute를 적용하는 것입니다. 이 패턴은 propertyNameSpecified 형식으로 만들어집니다. 예를 들어, "MyFirstName" 필드가 있을 경우 "MyFirstName"이라는 XML 요소를 생성할지 여부를 XmlSerializer에 지시하는 "MyFirstNameSpecified" 필드를 만들어야 합니다. 다음 예제에서 이를 확인할 수 있습니다.

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

기본 Serialization 재정의

적절한 특성 중 하나를 만들고 XmlAttributes 클래스의 인스턴스에 이를 추가하여 개체 집합과 해당 필드 및 속성에 대한 serialization을 재정의할 수도 있습니다. 이러한 방식으로 serialization을 재정의하면 두 가지 효과를 얻을 수 있습니다. 첫째, 소스에 액세스할 수 없는 경우에도 DLL에 있는 개체의 serialization을 제한하고 확장할 수 있으며 둘째, serialize할 수 있는 클래스 집합을 하나만 만들어도 개체를 serialize할 때는 여러 방법을 사용할 수 있습니다. 자세한 내용은 XmlAttributeOverrides 클래스와 방법: 파생 클래스의 serialization 제어를 참조하십시오.

개체를 serialize하려면 Serialize 메서드를 호출하고 개체를 deserialize하려면 Deserialize 메서드를 호출합니다.

XML 네임스페이스를 XML 문서에 추가하려면 XmlSerializerNamespaces를 참조하십시오.

참고

XmlSerializer를 사용하면 IEnumerable 또는 ICollection을 구현하는 클래스를 특별히 처리할 수 있습니다. IEnumerable을 구현하는 클래스는 단일 매개 변수를 취하는 공용 Add 메서드를 구현해야 합니다. Add 메서드의 매개 변수는 GetEnumerator에서 반환된 값에 대한 Current 속성에서 반환된 형식과 같거나, 해당 기본 형식 중 하나여야 합니다. IEnumerable뿐 아니라 ICollection을 구현하는 클래스(예: CollectionBase)는 정수를 취하는 인덱싱된 공용 Item 속성(C#에서 인덱서)이 있어야 하며, 정수 형식의 공용 Count 속성도 있어야 합니다. Add 메서드의 매개 변수는 Item 속성에서 반환된 형식과 같거나, 해당 기본 형식 중 하나여야 합니다. ICollection을 구현하는 클래스의 경우, serialize되는 값은 GetEnumerator를 호출하지 않고, 인덱싱된 Item 속성에서 검색됩니다.

개체를 deserialize하려면 임시 디렉터리에 대한 쓰기 권한이 있어야 합니다. 이러한 권한은 TEMP 환경 변수를 통해 정의됩니다.

동적으로 생성되는 어셈블리

성능을 높이기 위해 XML serialization 인프라에서는 지정된 형식을 serialize 및 deserialize하는 어셈블리를 동적으로 생성하며 그러한 어셈블리를 찾아서 재사용합니다. 이 동작은 다음과 같은 생성자를 사용하는 경우에만 발생합니다.

System.Xml.Serialization.XmlSerializer(Type)

System.Xml.Serialization.XmlSerializer(Type,String)

다른 생성자를 사용하면 동일한 어셈블리의 여러 버전이 생성되어 언로드되지 않음으로 인해 메모리 누수가 발생하고 성능이 떨어집니다. 이 문제를 해결하는 가장 간단한 방법은 위 두 가지 생성자 중 하나를 사용하는 것입니다. 그렇지 않은 경우에는 다음 예제에서와 같이 어셈블리를 Hashtable에 캐시해야 합니다.

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.
}
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 및 제네릭 목록의 Serialization

XmlSerializer는 다음을 serialize 또는 deserialize할 수 없습니다.

예제

다음 예제는 두 개의 클래스, PurchaseOrderTest를 포함합니다. PurchaseOrder 클래스에는 단일 구매에 대한 정보가 들어 있으며 Test 클래스에는 구매 주문을 만들고, 만들어진 구매 주문을 읽는 메서드가 들어 있습니다.

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
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 + "'");
   }
}
#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();
}
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 98, Windows 2000 SP4, Windows CE, Windows Millennium Edition, Windows Mobile for Pocket PC, Windows Mobile for Smartphone, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition

.NET Framework에서 모든 플래폼의 모든 버전을 지원하지는 않습니다. 지원되는 버전의 목록은 시스템 요구 사항을 참조하십시오.

버전 정보

.NET Framework

2.0, 1.1, 1.0에서 지원

.NET Compact Framework

2.0에서 지원

참고 항목

참조

XmlSerializer 멤버
System.Xml.Serialization 네임스페이스
XmlAttributeOverrides 클래스
XmlAttributes 클래스
XmlSerializer 클래스
XmlAttributes.XmlText 속성
XmlAttributes 클래스

기타 리소스

XML Serialization 소개
방법: XML 스트림의 대체 요소 이름 지정
특성을 사용하여 XML Serialization 제어
XML Serialization 예
XML 스키마 정의 도구(Xsd.exe)
방법: 파생 클래스의 serialization 제어
<dateTimeSerialization> 요소
<xmlSerializer> 요소