Menu Close

第37章 要素の置換

概要

XML スキーマの置換グループを使用すると、最上位 (または先頭) 要素を置き換えることができる要素のグループを定義できます。これは、共通のベース型を共有する複数の要素がある場合や、交換可能な要素が含まれる場合に便利です。

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

概要

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

本質的に、置換グループを使用すると、汎用要素を使用して指定できる要素のコレクションを構築できます。たとえば、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" />

型の制限

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

例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>