前回に引き続き,今回もXML Schemaを使ったはてなダイアリー形式XML文書の構造定義を通してXML Schemaの基本構文を学習します。

図1●はてなダイアリー形式XML文書の構造

例1 図1の構造のXML Schemaの定義例
※行番号は解説の便宜上付けたもので,実際のコードには必要ありません

[画像のクリックで拡大表示]

◇xs:attribute要素

<xs:attribute name="date" type="xs:string" use="required" />

 xs:attribute要素(例1の17行目,18行目)を使用して,属性を定義します。xs:attribute要素のname属性に属性名を指定し,type属性にデータ型を指定します。ただし,指定できるデータ型は必ず単純型(組み込み単純型,または独自の単純型)となります。default属性にデフォルト値,fixed属性に固定値を指定できますが,xs:element要素と同様に,default属性とfixed属性を同時に指定することはできません。

 またuse属性には,属性を必ず記述する(required),属性の記述を省略できる(optional)など,属性の出現を任意に指定することができます。ただし,default属性を記述する場合は,use属性の値はoptional(省略可能)にしなくてはなりません。use属性に指定できる値とDTDとの対応を表1にまとめましたので参照してください。


表1●xs:attribute要素のuse属性値とDTDとの対応

use属性値説明DTDとの対応
required属性の記述が必須となる#REQUIRED
optional属性の記述が省略可能となる#IMPLIED
prohibited属性の記述を禁止することができる(属性指定を含む定義を
再利用により制限し,その属性の記述を禁止する)
なし

確認問題1
次の属性宣言のうち,正しいものを選択してください。なお,XML Schemaの名前空間接頭辞は「xs」とします。

(a)
 

(b)
 

(c)
 

(d)
 

 正解は(a),(b),(d)です。(c)はuse属性が「required」なのに,default属性を指定しています。use属性が「required」の場合,属性の記述が必須となりますので,デフォルト値を設定しても意味がありません。default属性で属性に対するデフォルト値を設定する場合には,use属性を「optional」にしなければなりません。

◇xs:complexType要素

  <xs:element name="day" type="dayType" />
<xs:complexType name="dayType">
<xs:sequence>
<xs:element ref="body" />
</xs:sequence>
<xs:attribute name="date" type="xs:string" use="required" />
<xs:attribute name="title" type="xs:string" use="required" />
</xs:complexType>

 xs:complexType要素(例1の12行目~19行目)は,複合型を定義する場合に使用します。複合型とは,要素の内容として子要素を持つ場合や要素が属性を持つ場合のことです。xs:complexType要素のname属性に型の名前を指定します。

 xs:complexType要素にはmixed属性があり,第6回の例4で説明した「混合内容」を定義する場合に使用します。mixed属性に"true"を指定することで混合内容を定義できます。デフォルトはfalseです。また,上記の例にもあるとおり,属性を持つ型を定義する場合には,xs:attribute要素を記述する場所はモデルグループ(後述)を記述した後になります。

例2 body要素に日記本文(文字データ)とcolor子要素を含めることができる場合

<!ELEMENT body (#PCDATA|color)*>

 上の例をXML Schemaで定義すると以下のようになります。

 このように,xs:complexType要素の子要素としてモデルグループを指定し,その中で要素の定義を行います。モデルグループとは,xs:complexType要素で定義する子要素の定義のことです。モデルグループの種類にはsequence,choice,allの3種類があり,3種類のうちのいずれか1つを記述します。xs:complexType要素の子要素として,直接xs:element要素を記述することはできません。ただし,空要素の定義を行う場合には,xs:complexType要素を空要素として記述します(例3)。

例3 空要素の定義

  <xs:element name="body" type="bodyType" />
<xs:complexType name="bodyType" />

 モデルグループとDTDの出現順序の対応を表2にまとめましたので,参照してください。


表2●モデルグループとDTDの出現順序との対応

モデルグループ説明DTDとの対応
sequencesequence内の要素が記述された順序で出現する,
choicechoice内の要素のいずれか1つが出現する|
allall内の要素が順序に関係なく,1回出現するなし

 sequence,choice,allには,minOccurs属性で出現回数の下限値を,maxOccurs属性で出現回数の上限値を指定することができます。minOccurs属性,maxOccurs属性のデフォルトはともに1となります。2つの属性には0以上の任意の整数を指定し,上限値が無制限となる場合には,maxOccurs属性に「unbounded」を指定します。ただし,allの場合のみ,minOccurs属性には,0または1,maxOccurs属性には1しか指定できません(表3)。


表3●モデルグループの出現回数の指定

モデルグループ下限値(minOccurs属性)上限値(maxOccurs属性)
sequence0以上の任意の整数 (デフォルト は1)0以上の任意の整数 (デフォルト は1)

無制限の場合,unbounded を指定
choice0以上の任意の整数 (デフォルト は1)0以上の任意の整数 (デフォルト は1)
無制限の場合、unbounded を指定
all0 または 1 (デフォルト は1)1

 なお,sequenceとchoiceはお互いにネストして使用することができます(例4)。

例4 sequenceとchoiceのネスト

  <xs:element name="information" type="informationType" />
<xs:complexType name="informationType" >
<xs:sequence maxOccurs="unbounded">
<xs:element name="Id" type="xs:string" />
<xs:element name="姓" type="xs:string" />
<xs:element name="名" type="xs:string" />
<xs:choice>
<xs:element name="固定電話" type="xs:string" />
<xs:element name="携帯電話" type="xs:string" />
</xs:choice>
</xs:sequence>
</xs:complexType>

確認問題2
次の型の宣言の中で正しいものを選択してください。なお,XML Schemaの名前空間接頭辞は「xs」とします。

(a)

    <xs:complexType name="root">
      <xs:all>
        <xs:sequence>
          <xs:element name="elem1" type="xs:string" />
          <xs:element name="elem2" type="xs:string" />
          <xs:element name="elem3" type="xs:string" />
        </xs:sequence>
      </xs:all>
      <xs:attribute name="att1" type="xs:string" />
    </xs:complexType>

(b)

    <xs:complexType name="root">
      <xs:attribute name="att1" type="xs:string" />
      <xs:sequence>
        <xs:element name="elem1" type="xs:string" />
        <xs:choice>
          <xs:element name="elem2" type="xs:string" />
          <xs:element name="elem3" type="xs:string" />
        </xs:choice>
      </xs:sequence>
    </xs:complexType>

(c)

    <xs:complexType name="root">
      <xs:choice>
        <xs:element name="elem1" type="xs:string" />
        <xs:sequence>
          <xs:element name="elem2" type="xs:string" />
          <xs:element name="elem3" type="xs:string" />
        </xs:sequence>
      </xs:choice>
      <xs:attribute name="att1" type="xs:string" />
    </xs:complexType>

(d)

    <xs:complexType name="root">
      <xs:element name="elem1" type="xs:string" />
      <xs:element name="elem2" type="xs:string" />
      <xs:element name="elem3" type="xs:string" />
      <xs:attribute name="att1" type="xs:string" />
    </xs:complexType>


 正解は(c)です。(a)は,モデルグループallとsequenceがネストしています。モデルグループのネストが許されているのは,sequenceとchoiceの組み合わせだけです。(b)はモデルグループのネストは正しく記述されていますが,属性を記述する位置に誤りがあります。属性を記述する位置は,モデルグループの定義の後,xs:complexType要素の終了タグの前となります。(c)は正しく定義されています。(d)はxs:complexType要素の子要素としてxs:element要素が記述されています。xs:complexType要素の子要素として,直接xs:element要素を記述することはできません。必ずsequence,choice,allのいずれかの子要素として記述します。

野中 康弘
インフォテリア 教育部 エンジニア。十数年間システム開発に携わり,そのうちの半分をデータベース管理者として奮闘する。現在は,インフォテリア認定教育センターのサポートや,XML技術者認定制度の「XMLマスター」に対応したコーステキストの開発などを担当している。