MaxOccurs 属性のバインディング サポート

このトピックの対象は、レガシ テクノロジに特定されています。XML Web サービスと XML Web サービス クライアントは以下を使用して作成してください。 Windows Communication Foundation.

.NET Framework では、maxOccurs 属性のバインドを一部サポートしています。

maxOccurs 属性を指定できるほとんどの要素について、Xsd.exe では値 01 と解釈され、配列フィールドではないフィールドが作成されます。1 を超える値は unbounded と解釈され、配列フィールドが作成されます。動作は要素によって異なります。

説明

maxOccurs 属性や minOccurs 属性を指定したエンティティでは、XML ドキュメントでこの属性に対応する位置にそのエンティティを連続して指定できる回数が制約されます。

これらの属性は、複合型定義でのみ使用できます。したがって、<element> 要素または <group> 要素でこれらの属性を使用するためには、これらの属性はローカル宣言にするか、(グローバル宣言そのものではなく) グローバル宣言への参照にする必要があります。

.NET Framework のプログラミング言語には、XML スキーマ複合型を持つバインディング クラスに対する maxOccurs 属性や minOccurs 属性に直接対応するソース コードの要素がありません。

Xsd.exe によって XML スキーマ ドキュメントからソース コードを生成する場合や逆変換を行う場合、maxOccurs 属性は、その属性が使用される XML スキーマ定義言語要素に応じて解釈が異なります。次の表に、要素ごとの解釈を示します。

要素 解釈

<element>

次の値を使用できます。

  • 1 : その要素のデータ型に対応する型のフィールドが作成されます。

  • 0 : Xsd.exe では値 0 を処理できません。代わりに、既定の値である 1 として処理されます。

  • unbounded : その要素のデータ型に対応する型の配列フィールドが作成されます。

  • 2 以上のすべての整数 : 値 unbounded と同様に、その要素のデータ型に対応する型の配列フィールドが作成されます。XmlValidatingReader クラスを使用して、スキーマ オブジェクト モデルで表された XML スキーマ ドキュメントに対して XML ドキュメントを有効化すると、1 を超える値を適用できます。

<group>

<group> 要素の場合、maxOccurs の値 0 は、Xsd.exe で 1 と解釈され、maxOccurs1 を超える値は、unbounded と解釈されます。

ただし、既定で、<group> 要素で maxOccurs="unbounded" と指定されている場合には、各子要素が maxOccurs="unbounded" と指定されていると見なされます。たとえば、<group> 要素の各子要素が <element> 要素である場合、作成されるクラスに生成される各フィールドは、対応する型の配列になります。

maxOccurs1 を超える値を持つグループが含まれるスキーマを正常にインポートするには、Xsd.exe で /order コマンド ライン オプションを使用することをお勧めします。このオプションを使用すると、グループ全体が 1 つの配列としてインポートされ、グループのそれぞれの要素に XmlElementAttribute 属性が適用されます。配列の型は、要素の型によって決まります。配列の型は、すべての要素を代入できる最派生型になります。つまり、Type1 型および Type2 型というどちらも TypeBase から派生した型の要素がグループに含まれる場合、配列は TypeBase 型になります。共通の基本型が存在しない場合は、Object 型になります。これに関連する例については、このトピックの最後にある <sequence> の例を参照してください。

<all>

maxOccurs 属性に対する有効な値は 1 のみになります。Xsd.exe は、無効な値があるとエラーを報告します。

<any>

使用可能な値 :

  • 1 : Xsd.exe は、System.Xml.Serialization.XmlAnyElementAttribute 属性を持つ System.Xml.XmlElement 型のフィールドを作成します。この属性を使用すると、クラスの他の使用可能なメンバーで識別される非 XML 型に任意の XML 属性をバインドしなくても、クラスでその XML 属性を表すことができます。

  • 0 : Xsd.exe は値 0 を処理できません。代わりに、既定の値である 1 として処理されます。

  • unbounded : XmlAnyElement 属性を持つ XmlElement の配列が作成されます。

  • 2 以上のすべての整数 : 値 unbounded と同様に、XmlAnyElement 属性を持つ XmlElement の配列が作成されます。XmlValidatingReader クラスを使用して、スキーマ オブジェクト モデルで表された XML スキーマ ドキュメントに対して XML ドキュメントを有効化すると、1 を超える値を適用できます。

<choice>

<choice> 要素は、2 つ以上の子要素を持ちます。それぞれの子要素は、要素または要素のグループを表します。この要素を含むインスタンス ドキュメントの指定された場所には、この子要素エンティティのうちのいずれか 1 つだけを指定できます。選択肢は、要素名ごとに異なる必要があります。また、型ごとに異なる場合もあり、グループの場合は番号ごとに異なります。詳細については、<choice> 要素のトピックを参照してください。

<choice> 要素では、<element> 要素および <any> 要素と同様に、maxOccurs の値 0 は Xsd.exe によって 1 と解釈され、maxOccurs の 1 を超える値は unbounded と解釈されます。

値が 1 の場合、Xsd.exe では共通の型または共通の基本型のフィールドが作成されます。各子要素ごとに、そのフィールドに対して XmlElementAttribute 型の属性が適用されます。各子要素の型が一致している場合、Xsd.exe では XmlChoiceIdentifierAttribute 型の属性が生成されます。このとき、2 番目のフィールドには、各子要素を示す列挙型が設定されます。この機能の詳細および例については、<choice> 要素を参照してください。

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

<sequence>

<sequence> 要素の場合も上の大部分の要素と同様に、maxOccurs の値 0 は Xsd.exe によって 1 と解釈され、maxOccurs の 1 を超える値は unbounded と解釈されます。

ただし、<sequence> 要素で maxOccurs="unbounded" と指定されている場合には、各子要素が maxOccurs="unbounded" と指定されていると見なされます。たとえば、<sequence> 要素の各子要素が <element> 要素である場合、作成されるクラスに生成される各フィールドは、対応する型の配列になります。逆変換を行って新しい XSD ドキュメントを作成する場合、このフィールド構造は、指定された数の <element maxOccurs="unbounded"> 要素を持つ <sequence maxOccurs="1"> 要素にバインドされます。

グループに含まれる各要素に XmlElementAttribute 属性が適用されます。配列の型は、要素の型によって決まります。配列の型は、すべての要素を代入できる最派生型になります。つまり、Type1 型および Type2 型というどちらも TypeBase から派生した型の要素がグループに含まれる場合、配列は TypeBase 型になります。共通の基本型が存在しない場合は、Object 型になります。これに関連する例については、このトピックの最後にある <sequence> の例を参照してください。

Xsd.exe でアセンブリ内の一連のクラスから XML スキーマ ドキュメントを生成する場合には、上の変換とは逆の変換処理が行われ、単一のインスタンスからは値 1maxOccurs が作成され、配列からは値 unboundedmaxOccurs が作成されます。

Xsd.exe では、maxOccurs の値 unbounded は配列にバインドされますが、配列の親要素が存在する場合、maxOccurs の値 1 はその親要素にバインドされます。

既定の System.Xml.Serialization.XmlArrayAttribute 属性が配列に適用される場合、配列の親要素を表すために、名前が ArrayOf で始まるスキーマ データ型が作成されます。配列に対して、この属性ではなく System.Xml.Serialization.XmlElementAttribute 属性が適用される場合、その配列要素はインスタンス ドキュメント内で、クラスにバインドする要素の各子要素として表されます。配列のバインディングの詳細については、「属性を使用した XML シリアル化の制御」を参照してください。

配列のバインディングに関する補足説明 1 を超える値から配列への変換を理解するために、特定の型のオブジェクトを宣言する場合と、そのオブジェクトに値 (実際には、スタック内またはヒープ内のメモリの位置) を代入する場合の違いを考察します。次の XSD 要素を考えます。

<xsd:element minOccurs="5" maxOccurs="5" name="items" type="xsd:token" />

手動でコードを作成する場合は、public string[] items のように、型宣言時には配列サイズ 5 を表明しません。その代わり、items = new string[5] のように、値の割り当て時に配列のサイズを表明します。

Xsd.exe が XML スキーマから生成するソース コードの種類は、型宣言、フィールド宣言、および型やフィールドに属性として適用できるメタデータだけです。オブジェクトに値を割り当てると、そのスコープを超えて拡張されます。

1 よりも大きい値にする場合は、スキーマ オブジェクト モデル (SOM: Schema Object Model) で表された XML スキーマ ドキュメントに対して、XML ドキュメントを XmlValidatingReader クラスを使用して検証します。SOM では、System.Xml.Schema.XmlSchemaParticle.MaxOccurs プロパティおよび System.Xml.Schema.XmlSchemaParticle.MaxOccursString プロパティを使用します。これらのプロパティは、maxOccurs 属性を設定できるすべての要素に適用されます。

Example

複合型定義における入力 XML スキーマの <choice> 要素

<xsd:choice maxOccurs="unbounded">
    <xsd:element name="stringA" type="xsd:string"/>
    <xsd:element name="stringB" type="xsd:string"/>
</xsd:choice>

上の XML スキーマ ドキュメントから生成される C# クラスの関連部分と、この要素の選択肢を示す列挙型 (対象の名前空間が http://example.org/ であると仮定)

    [System.Xml.Serialization.XmlElementAttribute("stringA", typeof(string))]
    [System.Xml.Serialization.XmlElementAttribute("stringB", typeof(string))]
    [System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemsElementName")]
    public string[] Items;
        
    [System.Xml.Serialization.XmlElementAttribute("ItemsElementName")]
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public ItemsChoiceType[] ItemsElementName;
...
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/", IncludeInSchema=false)]
public enum ItemsChoiceType {
    stringA,
    stringB,
}

上の C# ソース コードをコンパイルして生成される複合型は、元の複合型と実質的に同一です。

<sequence>

Example

入力 XML スキーマ ドキュメントには、1 を超える値の maxOccurs が指定されたシーケンスが含まれます。

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
      xmlns="http://example.org/" targetNamespace="http://example.org/" elementFormDefault="qualified">
  <xsd:element name="ComplexInstance">
   <xsd:complexType>
     <xsd:sequence maxOccurs="unbounded">
       <xsd:element name="Field1" type="xsd:token"/>
       <xsd:element name="Field2" type="xsd:int" />
     </xsd:sequence>
   </xsd:complexType>
  </xsd:element>
</xsd:schema>

上記の XML スキーマ ドキュメントからコマンド ライン オプションの指定なしで生成される C# クラス

[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://example.org/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://example.org/", IsNullable=false)]
public class ComplexInstance {        
    [System.Xml.Serialization.XmlElementAttribute("Field1", DataType="token")]
    public string[] Field1;
        
    [System.Xml.Serialization.XmlElementAttribute("Field2")]
    public int[] Field2;
}

上記の C# ソースからコンパイルされたアセンブリから生成される XML スキーマ複合型

<xs:complexType name="ComplexInstance">
  <xs:sequence>
    <xs:element minOccurs="0" maxOccurs="unbounded" name="Field1" type="xs:token" />
    <xs:element minOccurs="0" maxOccurs="unbounded" name="Field2" type="xs:int" />
  </xs:sequence>
</xs:complexType>

このように、生成されるスキーマは元のスキーマに対応しません。1 を超える値の maxOccurs が指定されたシーケンスを含むスキーマを適切にインポートするには、/order コマンド ライン オプションを使います。この場合の結果を次に示します。

[System.Xml.Serialization.XmlTypeAttribute

(Namespace="http://example.org/")]

[System.Xml.Serialization.XmlRootAttribute

(Namespace="http://example.org/", IsNullable=false)]

public partial class ComplexInstance

{

/// <remarks/>

[System.Xml.Serialization.XmlElementAttribute

("Field1", typeof(string), DataType="token", Order=0)]

[System.Xml.Serialization.XmlElementAttribute("Field2",

typeof(int), Order=0)]

public object[] Items;

}

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

参照

リファレンス

System.Xml.Schema.XmlSchemaParticle.MaxOccurs
System.Xml.Schema.XmlSchemaParticle.MaxOccursString
XmlSchemaAll
XmlSchemaAny
XmlSchemaChoice
XmlSchemaElement
XmlSchemaGroupRef
XmlSchemaSequence