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 の値 0 は、Xsd.exe によって 1 と解釈され、maxOccurs の 1 を超える値は、unbounded と解釈されます。

値が 1 の場合、Xsd.exe は、「Differentiating by Type」および「Differentiating by Name」で説明したコードを生成します。

値が unbounded の場合、Xsd.exe で行われるバインディングは同じですが、選択肢に対応して生成されるフィールドは適切な型の配列になります。各子要素の型が同じ場合、XmlChoiceIdentifier 属性で識別される 2 番目のフィールドの型は、生成される列挙型の配列になります。2 つ目の配列の各要素では、1 つ目の配列の対応する要素の要素名を指定します。

MaxOccurs 属性のバインディング サポート 属性を参照してください。

minOccurs

XML スキーマ ドキュメントからソース コードを生成する場合、Xsd.exe は、<choice> 要素に適用された minOccurs 属性を無視します。

クラスから XML スキーマ ドキュメントを生成するとき、Xsd.exe は単一のオブジェクトを表す場合は minOccurs の値 1、配列を表す場合は minOccurs の値 0 を持つ <choice> 要素を作成します。

MinOccurs 属性のバインディング サポート 属性を参照してください。

使用可能な親要素 : <choice>、<complexType><extension><group><restriction><sequence>

使用可能な子要素 : <annotation><any><element><group><sequence>、<choice>

参照

リファレンス

XmlSchemaChoice