XML Schema達人への道
最終回:スキーマ文書のカスタマイズ
(株)日本ユニテック
奥井 康弘
<この記事はDigital
Xpress 2001 Vol.9(6-7月号)に掲載されたものです>
さて、今回はこのシリーズの最終回です。スキーマ文書をカスタマイズするという観点で以下の機能について説明します。
●スキーマ文書を分割して管理する方法
●構造定義の一部や属性定義の一部を共有する方法
●既存のスキーマ文書の構造定義の一部や属性定義の一部を修正する方法
さあ、XML Schema の達人の域まであと一歩です。がんばってください。
スキーマ文書の分割
前々回の記事で、他の名前空間をインポートする機能について説明しました。この機能と似たものとして、同じ名前空間を表現するスキーマを複数のスキーマ文書に分割して管理するために使用するインクルード(include)という機能があります。これは、分割されたスキーマ文書のファイルを取り込む機能です。指定の仕方がインポートと似ているとはいえ、インポートが名前空間を「利用する」という論理的な宣言であったのに対し、インクルードは「ファイルを読み込む」という物理的な指定であるという点で概念的に大きな違いがあります。
インクルードを行うには次のように書きます。
同じ対象名前空間の他のスキーマ文書をインクルードする方法
<xsd:include schemaLocation=" インクルードされるスキーマ文書のURI"/>
|
インクルードされるスキーマ文書の対象名前空間は、インクルードを行うスキーマ文書の対象名前空間と同じでなければなりません。インクルードは、同じ名前空間のスキーマ文書を取り込むものだからです。
【スキーマ文書:book.xsd】
さて、例を見てみましょう。次のスキーマ文書は同じ対象名前空間のbasic.xsd をインクルードしています。
【インクルードされるスキーマ文書:basic.xsd】
<?xml version="1.0"?>
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.utj.co.jp/schemas/book">
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="para" type="xsd:string"/>
</xsd:schema> |
【book.xsdに従う XMLインスタンス】
<?xml version="1.0"?>
<book
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.utj.co.jp/schemas/book"
xsi:schemaLocation=
"http://www.utj.co.jp/schemas/book/book.xsd">
<title>XML の館</title>
<body>
<para> 昔遠い国にXML 城と呼ばれるお城があった。そこには....</para>
</body>
</book> |
読み込むスキーマ文書が複数ある場合は、その数に合わせてxsd:include を何回でも指定することができます。
さて、さきほど、インクルードされるスキーマ文書の名前空間は、インクルードを行うスキーマ文書の対象名前空間と一致していなければならないという説明をしましたが、例外として、対象名前空間を指定しないスキーマ文書は、どんな名前空間のスキーマ文書によってインクルードされてもエラーにはなりません。これは、「対象名前空間を持たない」という性質が、名前空間に関して白紙の状態であると考えることができるからです。その際、対象名前空間を持たないスキーマ文書をインクルードすると、インクルードされたスキーマ文書の中で定義された宣言や型定義は、インクルードを行ったスキーマ文書の対象名前空間に属すものと解釈されます。
インクルードが「ファイルの展開機能」であると考えれば、これを理解することができるでしょう。
次に、さきほどの例のbasic.xsd を対象名前空間を持たないスキーマ文書に変えてみましょう。これをbasic2.xsd
とします。
【スキーマ文書:book2.xsd】
<?xml version="1.0"?>
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.utj.co.jp/schemas/book"
xmlns="http://www.utj.co.jp/schemas/book">
<xsd:include schemaLocation="basic2.xsd"/>
<xsd:element name="book">
<xsd:complexType>
<xsd:sequence>
<xsd:element
ref="title"/>
<xsd:element
ref="body"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="body">
<xsd:complexType>
<xsd:sequence>
<xsd:element
ref="para"maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema> |
【対象名前空間を持たないスキーマ文書: basic2.xsd】
<?xml version="1.0"?>
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="para" type="xsd:string"/>
</xsd:schema> |
ここでは、スキーマ文書book2.xsd において、対象名前空間をデフォルト名前空間として宣言している(xmlns="http://www.utj.co.jp/schemas/book")ので気が付かないのですが、実は、<xsd:element
ref="book"/>など、他で宣言された要素を参照するときには、その要素が属する名前空間を表す接頭辞を付けて参照しなければなりません。この場合は、デフォルト名前空間が効いていて、<xsd:element
ref="book"/>でよいのですが、たとえば、xmlns:bk="http://www.utj.co.jp/schemas/book"
と宣言すると、その中で宣言されたbook 要素を<xsd:element ref="bk:book"/>として参照しなければなりません。
さて、その場合、インクルードされた対象名前空間を持たないスキーマ文書で宣言された要素title 、para を参照するときには、名前空間接頭辞を付けるのでしょうか?答えは「付けなければならない」です。つまり、次のように書くことになります。
【名前空間接頭辞を使ったスキーマ文書: book3.xsd】
<?xml version="1.0"?>
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.utj.co.jp/schemas/book"
xmlns:bk="http://www.utj.co.jp/schemas/book">
<xsd:include schemaLocation="basic2.xsd"/>
<xsd:element name="book">
<xsd:complexType>
<xsd:sequence>
<xsd:element
ref="bk:title"/>
<xsd:element
ref="bk:body"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="body">
<xsd:complexType>
<xsd:sequence>
<xsd:element
ref="bk:para" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema> |
このように、title 要素、para 要素も、すでにインクルードした側の名前空間に属すものとして参照します。これは、やはりインクルードが「ファイル展開機能」であることに由来します。
>>続いて「XMLスキーマで定義を一部共有する方法」についてみてみましょう。
関連サービス
XMLスキーマの策定、作成業務
|