第37章 元素置換

概要

XML スキーマ置換グループを使用すると、最上位またはヘッドの要素を置き換えることができる要素のグループを定義できます。これは、共通の基本タイプを共有する複数の要素がある場合、または交換可能である必要がある要素を持つ場合に役立ちます。

37.1. XML スキーマの置換グループ

概要

置換グループは XML スキーマの機能であり、そのスキーマから生成されたドキュメント内の別の要素を置き換えることができる要素を指定できます。置換可能な要素は head 要素と呼ばれ、スキーマのグローバルスコープで定義する必要があります。置換グループの要素は、head 要素と同じタイプ、または head 要素のタイプから派生したタイプである必要があります。

基本的に、置換グループを使用すると、汎用要素を使用して指定できる要素のコレクションを作成できます。たとえば、3 種類のウィジェットを販売する会社の注文システムを構築している場合、3 種類すべてのウィジェットの共通データのセットを含む汎用ウィジェット要素を定義できます。次に、ウィジェットのタイプごとに、より具体的なデータセットを含む置換グループを定義できます。コントラクトでは、ウィジェットのタイプごとに特定の順序付け操作を定義する代わりに、汎用ウィジェット要素をメッセージ部分として指定できます。実際のメッセージが作成されるとき、メッセージには置換グループの任意の要素を含めることができます。

構文

置換グループは、XML スキーマの element 要素の substitutionGroup 属性を使用して定義されます。substitutionGroup 属性の値は、定義される要素が置換する要素の名前です。たとえば、先頭要素が widget の場合は、属性 substitutionGroup="widget" を woodWidget という名前の要素に追加すると、widget 要素が使用されるあらゆる場所で woodWidget 要素を置換できることを指定します。これは、例37.1「代替グループの使用」 に示されています。

例37.1 代替グループの使用

<element name="widget" type="xsd:string" />
<element name="woodWidget" type="xsd:string"
         substitutionGroup="widget" />

タイプの制約

置換グループの要素は、head 要素と同じタイプであるか、head 要素のタイプから派生したタイプである必要があります。たとえば、先頭要素の型が xsd:int である場合、置換グループのすべてのメンバーは xsd:int 型または xsd:int から派生する型である必要があります。例37.2「複雑なタイプの置換グループ」 に示すような置換グループを定義することもできます。ここで、置換グループの要素は、head 要素のタイプから派生したタイプです。

例37.2 複雑なタイプの置換グループ

<complexType name="widgetType">
  <sequence>
    <element name="shape" type="xsd:string" />
    <element name="color" type="xsd:string" />
  </sequence>
</complexType>
<complexType name="woodWidgetType">
  <complexContent>
    <extension base="widgetType">
      <sequence>
        <element name="woodType" type="xsd:string" />
      </sequence>
    </extension>
  </complexContent>
</complexType>
<complexType name="plasticWidgetType">
  <complexContent>
    <extension base="widgetType">
      <sequence>
        <element name="moldProcess" type="xsd:string" />
      </sequence>
    </extension>
  </complexContent>
</complexType>
<element name="widget" type="widgetType" />
<element name="woodWidget" type="woodWidgetType"
         substitutionGroup="widget" />
<element name="plasticWidget" type="plasticWidgetType"
         substitutionGroup="widget" />
<complexType name="partType">
  <sequence>
    <element ref="widget" />
  </sequence>
</complexType>
<element name="part" type="partType" />

置換グループの先頭要素 widget は、widgetType 型として定義されます。置換グループの各要素は、その型のウィジェットの注文に固有のデータを含むように widgetType を拡張します。

例37.2「複雑なタイプの置換グループ」のスキーマに基づいて、例37.3「置換グループを使用した XML ドキュメント」part 要素は有効です。

例37.3 置換グループを使用した XML ドキュメント

<part>
  <widget>
    <shape>round</shape>
    <color>blue</color>
  </widget>
</part>
<part>
  <plasticWidget>
    <shape>round</shape>
    <color>blue</color>
    <moldProcess>sandCast</moldProcess>
  </plasticWidget>
</part>
<part>
  <woodWidget>
    <shape>round</shape>
    <color>blue</color>
    <woodType>elm</woodType>
  </woodWidget>
</part>

抽象的な頭の要素

スキーマを使用して作成されたドキュメントには表示されない抽象ヘッド要素を定義できます。抽象ヘッド要素は、ジェネリッククラスのより具体的な実装を定義するための基礎として使用されるため、Java の抽象クラスに似ています。抽象ヘッドはまた、最終製品での一般的な要素の使用を防ぎます。

例37.4「抽象ヘッド定義」 に示すように、element 要素の abstract 属性を true に設定して、抽象先頭要素を宣言します。このスキーマを使用すると、有効な review 要素に positiveComment 要素または negativeComment 要素のいずれかを含めることができますが、comment 要素を含めることはできません。

例37.4 抽象ヘッド定義

<element name="comment" type="xsd:string" abstract="true" />
<element name="positiveComment" type="xsd:string"
         substitutionGroup="comment" />
<element name="negtiveComment" type="xsd:string"
         substitutionGroup="comment" />
<element name="review">
  <complexContent>
    <all>
      <element name="custName" type="xsd:string" />
      <element name="impression" ref="comment" />
    </all>
  </complexContent>
</element>