Share via


属性を使用した XML シリアル化の制御

属性を使用すると、オブジェクトの XML シリアル化を制御したり、同じ一連のクラスから代替 XML ストリームを作成したりできます。代替 XML ストリームの作成の詳細については、「方法 : XML ストリームの代替要素名を指定する」を参照してください。

Noteメモ :

生成された XML が W3C (World Wide Web Consortium) (www.w3.org) のドキュメント『Simple Object Access Protocol (SOAP) 1.1』のセクション 5 に準拠する必要がある場合は、「エンコード済み SOAP シリアル化を制御する属性」に示す属性を使用します。

既定では、XML 要素名は、クラス名またはメンバ名によって決まります。次の例に示すように、Book という名前の単純なクラスでは、ISBN という名前のフィールドから XML 要素タグ <ISBN> が生成されます。

Public Class Book
    Public ISBN As String
End Class
' When an instance of the Book class is serialized, it might 
' produce this XML:
' <ISBN>1234567890</ISBN>.
public class Book
{
    public string ISBN;
}
// When an instance of the Book class is serialized, it might 
// produce this XML:
// <ISBN>1234567890</ISBN>.

要素に新しい名前を付けると、既定の動作を変更できます。XmlElementAttributeElementName プロパティを設定することによってこれを実現する方法を次のコードに示します。

Public Class TaxRates
   < XmlElement(ElementName = "TaxRate")> _
    Public ReturnTaxRate As Decimal
End Class
public class TaxRates{
    [XmlElement(ElementName = "TaxRate")]
    public decimal ReturnTaxRate;
}

属性の詳細については、「属性を使用したメタデータの拡張」を参照してください。XML シリアル化を制御する属性の一覧については、「XML シリアル化を制御する属性」を参照してください。

配列のシリアル化の制御

XmlArrayAttribute 属性および XmlArrayItemAttribute 属性は、配列のシリアル化を制御できるようにデザインされています。これらの属性を使用すると、要素名、名前空間、および XML スキーマ (W3C (World Wide Web Consortium) (www.w3.org) のドキュメント『XML Schema Part 2: Datatypes』で定義されている XSD データ型) を制御できます。また、配列に挿入できる型も指定できます。

XmlArrayAttribute は、配列をシリアル化したときに生成される外側の XML 要素のプロパティを決定します。たとえば、下に示す配列をシリアル化すると、既定では Employees という名前の XML 要素が生成されます。この Employees 要素には、配列型 Employee の名前が付いた一連の要素が含まれます。

Public Class Group
    Public Employees() As Employee
End Class
Public Class Employee
    Public Name As String
End Class
public class Group{
    public Employee[] Employees;
}
public class Employee{
    public string Name;
}

シリアル化されたインスタンスは、次のようになります。

<Group>
<Employees>
    <Employee>
        <Name>Haley</Name>
    </Employee>
</Employees >
</Group>

XmlArrayAttribute を適用すると、この XML 要素の名前を次のように変更できます。

Public Class Group
    <XmlArray("TeamMembers")> _
    Public Employees() As Employee
End Class
public class Group{
    [XmlArray("TeamMembers")]
    public Employee[] Employees;
}

結果として、次のような XML が生成されます。

<Group>
<TeamMembers>
    <Employee>
        <Name>Haley</Name>
    </Employee>
</TeamMembers>

一方、XmlArrayItemAttribute は、配列内の項目をシリアル化する方法を制御します。この属性は、配列を返すフィールドに適用されることに注意してください。

Public Class Group
    <XmlArrayItem("MemberName")> _
    Public Employee() As Employees
End Class
public class Group{
    [XmlArrayItem("MemberName")]
    public Employee[] Employees;
}

結果として、次のような XML が生成されます。

<Group>
<Employees>
    <MemberName>Haley</MemberName>
</Employees>
</Group>

派生クラスのシリアル化

XmlArrayItemAttribute のもう 1 つの用途は、派生クラスをシリアル化することです。たとえば、Employee から派生した Manager という名前の別のクラスを前の例に追加できます。XmlArrayItemAttribute を適用しない場合は、この派生クラス型が認識されないため、コードは実行時に失敗します。対応策として、この属性を 2 回適用し、有効な型 (基本および派生) ごとにそれぞれ Type プロパティを設定します。

Public Class Group
    <XmlArrayItem(Type:=GetType(Employee)), _
    XmlArrayItem(Type:=GetType(Manager))> _
    Public Employees() As Employee
End Class
Public Class Employee
    Public Name As String
End Class
Public Class Manager
Inherits Employee
    Public Level As Integer
End Class
public class Group{
    [XmlArrayItem(Type = typeof(Employee)),
    XmlArrayItem(Type = typeof(Manager))]
    public Employee[] Employees;
}
public class Employee{
    public string Name;
}
public class Manager:Employee{
    public int Level;
}

シリアル化されたインスタンスは、次のようになります。

<Group>
<Employees>
    <Employee>
        <Name>Haley</Name>
    </Employee>
    <Employee xsi:type = "Manager">
        <Name>Ann</Name>
        <Level>3</Level>
    <Employee>
</Employees >
</Group>

要素のシーケンスとしての配列のシリアル化

また、次の例に示すように、配列を返すフィールドに XmlElementAttribute を適用して、配列を XML 要素のフラットなシーケンスとしてシリアル化することもできます。

Public Class Group
    <XmlElement> _
    Public Employees() As Employee
End Class
public class Group{
    [XmlElement]
    public Employee[] Employees;
}

シリアル化されたインスタンスは、次のようになります。

<Group>
<Employees>
    <Name>Haley</Name>
</Employees>
<Employees>
    <Name>Noriko</Name>
</Employees>
<Employees>
    <Name>Marco</Name>
</Employees>
</Group>

2 つの XML ストリームを区別するもう 1 つの方法は、XML スキーマ定義ツールを使用して、コンパイル済みのコードから XML スキーマ (XSD) ドキュメント ファイルを生成することです。XML スキーマ定義ツールの使用方法については、「XML スキーマ定義ツールと XML シリアル化」を参照してください。このフィールドに属性を適用しない場合、スキーマには要素が次のように記述されます。

<xs:element minOccurs="0" maxOccurs ="1" name="Employees" type="ArrayOfEmployee" />

このフィールドに XmlElementAttribute を適用した場合は、生成されるスキーマでは要素が次のように記述されます。

<xs:element minOccurs="0" maxOccurs="unbounded" name="Employees" type="Employee" /> 

ArrayList のシリアル化

ArrayList クラスには、さまざまなオブジェクトのコレクションを含めることができます。そのため、ArrayList は、配列とほとんど同じように使用できます。型指定されたオブジェクトの配列を返すフィールドを作成する代わりに、単一の ArrayList を返すフィールドを作成することもできます。ただし、配列の場合と同様に、ArrayList に含まれるオブジェクトの型を XmlSerializer に通知する必要があります。この処理を行うには、次の例に示すように、XmlElementAttribute の複数のインスタンスをフィールドに割り当てます。

Public Class Group
    <XmlElement(Type:=GetType(Employee)), _
    XmlElement(Type:=GetType(Manager))> _
    Public Info As ArrayList
End Class
public class Group{
    [XmlElement(Type = typeof(Employee)), 
    XmlElement(Type = typeof(Manager))]
    public ArrayList Info;
}

XmlRootAttribute と XmlTypeAttribute を使用したクラスのシリアル化の制御

XmlRootAttribute および XmlTypeAttribute という 2 つの属性は、いずれも 1 つのクラスにのみ適用できます。これらの属性は、非常に似ています。XmlRootAttribute は、シリアル化されたときに XML ドキュメントの開始要素と終了要素、つまりルート要素を表す 1 つのクラスにのみ適用できます。一方、XmlTypeAttribute は、ルート クラスを含む任意のクラスに適用できます。

たとえば、前の例では、Group クラスがルート クラスであり、そのすべてのパブリック フィールドとパブリック プロパティは、XML ドキュメント内の XML 要素になります。したがって、存在するルート クラスは 1 つだけです。XmlRootAttribute を適用すると、XmlSerializer によって生成される XML ストリームを制御できます。たとえば、要素名や名前空間を変更できます。

XmlTypeAttribute を使用すると、生成される XML のスキーマを制御できます。この機能は、XML Web サービスを通じてスキーマを公開する必要がある場合に便利です。XmlTypeAttributeXmlRootAttribute の両方を同じクラスに適用した例を次に示します。

<XmlRoot("NewGroupName"), _
XmlType("NewTypeName")> _
Public Class Group
    Public Employees() As Employee
End Class
[XmlRoot("NewGroupName")]
[XmlType("NewTypeName")]
public class Group{
    public Employee[] Employees;
}

このクラスをコンパイルし、XML スキーマ定義ツールを使用してそのスキーマを生成した場合は、Group を記述する次の XML が見つかります。

<xs:element name="NewGroupName" type="NewTypeName">

これに対し、クラスのインスタンスをシリアル化した場合は、XML ドキュメント内に NewGroupName だけが見つかります。

<NewGroupName>
    . . .
</NewGroupName>

XmlIgnoreAttribute を使用したシリアル化の防止

パブリック プロパティやパブリック フィールドをシリアル化する必要がない場合があります。たとえば、フィールドやプロパティは、メタデータを格納するために使用されることがあります。その場合は、このフィールドやプロパティに XmlIgnoreAttribute を適用すると、XmlSerializer がそれらのメンバをスキップするようになります。

参照

処理手順

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

概念

XML シリアル化を制御する属性
エンコード済み SOAP シリアル化を制御する属性
XML シリアル化の概要
XML シリアル化の例