連載
» 2004年02月11日 10時00分 公開

XMLテクニック集(10):XML Schemaで選択型の値を定義する (3/3)

[山田祥寛,@IT]
前のページへ 1|2|3       

外部のXML Schemaをインクルード/インポートする

アイコン

頻繁に使用するスキーマ定義を別ファイルとして保存しておき、ほかのXML Schemaに取り込んで再利用する場合、同一の名前空間なら<xsd:include>要素、異なる名前空間では<xsd:import>要素を使います。

カテゴリ XML Schema
関連要素 <xsd:include>、<xsd:import>
関連記事 XML Schemaで文字列パターンを定義する

 XML Schemaに用意されている<complexType>、<group>、<attributeGroup>要素などは、複雑になりがちなスキーマ文書をコンパクトに記述し、変更時のメンテナンシビリティを高めるための手法です。これらについては、別稿「XML Schemaで複雑型要素を定義する」「XML Schemaで要素モデルを定義する」「XML Schemaで属性グループを定義する」で紹介したとおりです。

 本稿では、1つのファイル内で定義を再利用するところからさらに一歩進んで、共通して利用可能なスキーマを別ファイルとして明確に分離し、より再利用性を高める方法について紹介します。対象となるXML文書については、別稿「XML Schemaで文字列パターンを定義する」で用いたbook.xmlを使用することにします。

books_include.xsd

<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:include schemaLocation="books_included.xsd" />
  <xsd:element name="books">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="book" type="book_type"
          minOccurs="0" maxOccurs="unbounded" />
      </xsd:sequence>
      <xsd:attribute name="name" type="xsd:string"
          use="required" />
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

books_included.xsd

<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:complexType name="book_type">
    <xsd:sequence>
      <xsd:element name="title" type="xsd:string" />
      <xsd:element name="author" type="xsd:string" />
      <xsd:element name="published" type="xsd:string" />
      <xsd:element name="price" type="xsd:positiveInteger" />
      <xsd:element name="publishDate" type="xsd:date" />
      <xsd:element name="category" type="xsd:string" />
      <xsd:element name="keywords" type="xsd:string" />
    </xsd:sequence>
    <xsd:attribute name="isbn" type="xsd:string"
        use="required" />
  </xsd:complexType>
</xsd:schema>


 books_include.xsdが基本となるスキーマ文書、books_included.xsdはbooks_include.xsdから呼び出されるスキーマ文書です。上記でポイントとなるのは、以下の2点です。

(1)外部スキーマをインクルードする<xsd:include>要素

 <xsd:include>要素は、<xsd:schema>直下の子要素として、かつ、<xsd:attribute>、<xsd:element>、<xsd:simpleType>、<xsd:complexType>、<xsd:group>、<xsd:attributeGroup>などよりも先に記述する必要があります。

 <xsd:include>要素のschemaLocation属性で指定された外部スキーマファイルは、あらかじめ呼び出し元のスキーマに含まれていたかのように動作します。もちろん、複数のスキーマから共通して呼び出すことが可能ですので、頻繁に使用されるカスタムのデータ型(拡張した複雑/単純型)を外部スキーマとして別ファイル化しておくことで、より保守性に富んだスキーマを記述可能になります。

(2)外部スキーマでも、<xsd:schema>要素は省略不可

 呼び出し元のスキーマに外部スキーマが「埋め込まれる」ようなイメージでとらえていると、よく間違いの原因となりますが、外部スキーマはそれ自体、完結したスキーマでなければなりません。つまり、呼び出し元のスキーマにすでに<xsd:schema>要素があるからといって、外部スキーマで<xsd:schema>を省略することはできません。外部スキーマにおいても、最上位要素は<xsd:schema>要素です。

(3)異なるターゲット名前空間では、<xsd:import>要素を使用

 なお、<xsd:include>要素は常に「同一の名前空間に属する」スキーマだけしか呼び出せない点に注意してください。もしターゲット名前空間が異なるスキーマを取り込みたい場合には、<xsd:import>要素を使用する必要があります。例えば、以下のようにです。

<xsd:import namespace="http://www.w3.org/XML/1998/namespace"
            schemaLocation="http://www.w3.org/2001/xml.xsd" />


 namespace属性には外部スキーマの名前空間URIを、schemaLocation属性にはスキーマの実際の位置を表すURIを指定します。もしパーサが名前空間URIのみでスキーマファイルの位置を「知ることができる」場合、schemaLocation属性を省略することも可能です。

<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />


 <xsd:import>要素も<xsd:include>要素と同様に、<xsd:schema>要素の最初の子要素として、かつ、<xsd:attribute>、<xsd:element>、<xsd:simpleType>、<xsd:complexType>、<xsd:group>、<xsd:attributeGroup>などよりも先に記述する必要があります。

実際に、妥当性検証を行いたい場合には、別稿「XML SchemaでXML文書の妥当性を検証する」のサンプルを参考にするとよいでしょう。変更個所は、XMLSchemaCache.addメソッドの第2引数(XML Schemaのファイル名)のみです。スキーマ文書を書いてみるだけでは、スキーマ文書そのものの妥当性を判断できませんが、パーサの処理を介することでスキーマの正否を確認できます。


前のページへ 1|2|3       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。