Choice 要素のバインディング サポート
このトピックの対象は、レガシ テクノロジに特定されています。XML Web サービスと XML Web サービス クライアントは以下を使用して作成してください。 Windows Communication Foundation.
.NET Framework では、<choice> 要素のバインディングがサポートされています。
個々の choice 要素の型が名前と共に異なる場合、Xsd.exe はパブリック メンバーに XmlElementAttribute 属性のみを適用します。名前だけが異なる場合、Xsd.exe は XmlChoiceIdentifierAttribute も適用し、選択を行うための別のロジックも追加します。
説明
<choice> 要素は、2 つ以上の子要素を持ちます。それぞれの子要素は、要素または要素のグループを表します。これは、指定されたインスタンス ドキュメントで、これらの要素の 1 つだけが指定した位置に表示できることを示します。選択肢は、要素名が異なる必要があります。また、選択肢は要素型が異なる場合もありますが、選択肢が <group> 要素などグループの場合には、要素の数も異なる場合があります。
グループの組み合わせがあいまいな場合には、予測できない結果が生じます。
型による差別化
各要素の型が名前ごとに異なる場合が最も単純です。次の <choice> 定義について考えます。
<xsd:choice>
<xsd:element name="numberA" type="xsd:int"/>
<xsd:element name="numberB" type="xsd:decimal"/>
</xsd:choice>
C# の場合、Xsd.exe はこの XML スキーマ コンテンツを次のコードに変換します。
[System.Xml.Serialization.XmlElementAttribute("numberA", typeof(int))]
[System.Xml.Serialization.XmlElementAttribute("numberB", typeof(System.Decimal))]
public object Item;
生成されるコードで、このフィールドは object 型になっていますが、XmlElementAttribute 属性も 2 つ指定されています。一方の属性では、この型を int 型のインスタンスにシリアル化するように指定されています。他方の属性では、System.Decimal 型のインスタンスにシリアル化するように指定されています。この場合、XmlSerializer クラスは、その時点でそのオブジェクトに代入されている型を使用します。次の int
オブジェクトへの代入では、<numberA>
要素が使用されます。
Item = 1;
選択肢に異なる XML スキーマ データ型がある場合、Xsd.exe は各データ型を別のクラスにバインドします。System.Object は、.NET Framework 型の階層構造のルート型であるため、生成されるフィールドは常にこの共通基本型に属しています。Object クラスは、最も汎用的な共通基本型です。
すべての選択肢が、<extension> 構造など共通の XML スキーマ定義データ型から派生している場合、このフィールドの型はそのデータ型のバインディングになります。たとえば、<choice>
要素の選択肢が、DerivedTypeA
型の要素 <a>
および DerivedTypeB
型の要素 <b>
であり、両方の型は BaseType
を拡張した型であるとします。C# の場合に生成されるソース コードを次に示します。
[System.Xml.Serialization.XmlElementAttribute("a", typeof(DerivedTypeA))]
[System.Xml.Serialization.XmlElementAttribute("b", typeof(DerivedTypeB))]
public BaseType Item;
名前による差別化
選択肢の型が同じ場合には、XmlChoiceIdentifierAttribute 属性を使用して、インスタンス ドキュメント作成時の要素名の選択が行われます。次の <choice>
定義について考えます。
<xsd:choice>
<xsd:element name="stringA" type="xsd:string"/>
<xsd:element name="stringB" type="xsd:string"/>
</xsd:choice>
Xsd.exe は、この XML スキーマ コンテンツを次のコードに変換します。
[System.Xml.Serialization.XmlElementAttribute("stringA", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("stringB", typeof(string))]
[System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemElementName")]
public string Item;
[System.Xml.Serialization.XmlIgnoreAttribute()]
public ItemChoiceType ItemElementName;
...
public enum ItemChoiceType {
stringA,
stringB,
}
Item
フィールドには 2 つの XmlElement 属性の他に 1 つの XmlChoiceIdentifier 属性があります。XmlChoiceIdentifier 属性に渡すパラメーターは、列挙定数インスタンスの名前です。対応する列挙型には、要素の選択肢が含まれています。列挙定数インスタンスには、その値がシリアル化されないように XmlIgnore 属性が設定されます。
開発者は、その後で、この列挙定数インスタンスに値を代入するためのコードを記述する必要があります。i
という名前のオブジェクトに対して上記の処理を行うコードを次に示します。
i.ItemElementName = ItemChoiceType.stringA;
詳細については、XmlChoiceIdentifierAttribute クラスのトピックを参照してください。
Example
<choice> 要素によるグループ化のさまざまな用途を示す入力 XML スキーマ ドキュメントを次に示します。
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://example.org/" xmlns="http://example.org/" elementFormDefault="qualified">
<xsd:element name="choicesInstance" type="MyChoicesType"/>
<xsd:complexType name="MyComplexType">
<xsd:sequence>
<xsd:element name="field1" type="xsd:string"/>
<xsd:element name="field2" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="DerivedTypeA">
<xsd:complexContent>
<xsd:extension base="MyComplexType">
<xsd:attribute name="extraInfoForA" type="xsd:string"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="DerivedTypeB">
<xsd:complexContent>
<xsd:extension base="MyComplexType">
<xsd:attribute name="extraInfoForB" type="xsd:string"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="MyChoicesType">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:choice>
<xsd:element name="stringA" type="xsd:string"/>
<xsd:element name="stringB" type="xsd:string"/>
</xsd:choice>
<xsd:choice>
<xsd:element name="numberA" type="xsd:int"/>
<xsd:element name="numberB" type="xsd:decimal"/>
</xsd:choice>
<xsd:choice>
<xsd:element name="complexA" type="MyComplexType"/>
<xsd:element name="complexB" type="MyComplexType"/>
<xsd:element name="simpleC" type="xsd:string"/>
</xsd:choice>
<xsd:choice>
<xsd:element name="derivedA" type="DerivedTypeA"/>
<xsd:element name="derivedB" type="DerivedTypeB"/>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
この XML スキーマ ドキュメントから生成される C# クラス :
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/")]
[System.Xml.Serialization.XmlRootAttribute("choicesInstance", Namespace="http://example.org/", IsNullable=false)]
public class MyChoicesType {
public string name;
[System.Xml.Serialization.XmlElementAttribute("stringA", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("stringB", typeof(string))]
[System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemElementName")]
public string Item;
[System.Xml.Serialization.XmlIgnoreAttribute()]
public ItemChoiceType ItemElementName;
[System.Xml.Serialization.XmlElementAttribute("numberA", typeof(int))]
[System.Xml.Serialization.XmlElementAttribute("numberB", typeof(System.Decimal))]
public object Item1;
[System.Xml.Serialization.XmlElementAttribute("complexA", typeof(MyComplexType))]
[System.Xml.Serialization.XmlElementAttribute("complexB", typeof(MyComplexType))]
[System.Xml.Serialization.XmlElementAttribute("simpleC", typeof(string))]
[System.Xml.Serialization.XmlChoiceIdentifierAttribute("Item2ElementName")]
public object Item2;
[System.Xml.Serialization.XmlIgnoreAttribute()]
public Item2ChoiceType Item2ElementName;
[System.Xml.Serialization.XmlElementAttribute("derivedA", typeof(DerivedTypeA))]
[System.Xml.Serialization.XmlElementAttribute("derivedB", typeof(DerivedTypeB))]
public MyComplexType Item3;
}
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/", IncludeInSchema=false)]
public enum ItemChoiceType {
stringA,
stringB,
}
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/")]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(DerivedTypeB))]
[System.Xml.Serialization.XmlIncludeAttribute(typeof(DerivedTypeA))]
public class MyComplexType {
public string field1;
public string field2;
}
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/")]
public class DerivedTypeA : MyComplexType {
[System.Xml.Serialization.XmlAttributeAttribute()]
public string extraInfoForA;
}
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/")]
public class DerivedTypeB : MyComplexType {
[System.Xml.Serialization.XmlAttributeAttribute()]
public string extraInfoForB;
}
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/", IncludeInSchema=false)]
public enum Item2ChoiceType {
complexA,
complexB,
simpleC,
}
上記の C# ソースをコンパイルしたアセンブリから生成される一次 XML スキーマ ドキュメント表示されていない部分は、複合型に対する任意のグローバル要素を定義するために生成される 2 つ目の .xsd ファイルです。
<xs:schema xmlns:tns="http://example.org/" elementFormDefault="qualified" targetNamespace="http://example.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="choicesInstance" type="tns:MyChoicesType" />
<xs:complexType name="MyChoicesType">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="name" type="xs:string" />
<xs:choice minOccurs="1" maxOccurs="1">
<xs:element minOccurs="0" maxOccurs="1" name="stringA" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="stringB" type="xs:string" />
</xs:choice>
<xs:choice minOccurs="1" maxOccurs="1">
<xs:element minOccurs="1" maxOccurs="1" name="numberA" type="xs:int" />
<xs:element minOccurs="1" maxOccurs="1" name="numberB" type="xs:decimal" />
</xs:choice>
<xs:choice minOccurs="1" maxOccurs="1">
<xs:element minOccurs="0" maxOccurs="1" name="complexA" type="tns:MyComplexType" />
<xs:element minOccurs="0" maxOccurs="1" name="simpleC" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="complexB" type="tns:MyComplexType" />
</xs:choice>
<xs:choice minOccurs="1" maxOccurs="1">
<xs:element minOccurs="0" maxOccurs="1" name="derivedB" type="tns:DerivedTypeB" />
<xs:element minOccurs="0" maxOccurs="1" name="derivedA" type="tns:DerivedTypeA" />
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:complexType name="MyComplexType">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="field1" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="field2" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="DerivedTypeA">
<xs:complexContent mixed="false">
<xs:extension base="tns:MyComplexType">
<xs:attribute name="extraInfoForA" type="xs:string" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="DerivedTypeB">
<xs:complexContent mixed="false">
<xs:extension base="tns:MyComplexType">
<xs:attribute name="extraInfoForB" type="xs:string" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
使用可能な属性 | バインディング サポート |
---|---|
id |
Xsd.exe ユーティリティでは、一意な識別子を提供するための id 属性は無視されます。 |
maxOccurs |
<choice> 要素の場合、maxOccurs の値 値が 値が MaxOccurs 属性のバインディング サポート 属性を参照してください。 |
minOccurs |
XML スキーマ ドキュメントからソース コードを生成する場合、Xsd.exe は、<choice> 要素に適用された minOccurs 属性を無視します。 クラスから XML スキーマ ドキュメントを生成するとき、Xsd.exe は単一のオブジェクトを表す場合は minOccurs の値 MinOccurs 属性のバインディング サポート 属性を参照してください。 |
使用可能な親要素 : <choice>、<complexType>、<extension>、<group>、<restriction>、<sequence>
使用可能な子要素 : <annotation>、<any>、<element>、<group>、<sequence>、<choice>