連載
» 2004年03月31日 00時00分 公開

SEのためのXML Schema入門(5):ユーザー独自のデータ型を作ろう

この連載では、XML Schemaについて解説します。簡単なXMLの構造をXML Schemaにより記述できるようになることを目標に、XML Schemaの概要、要素・属性の定義、Complex TypeやSimple Type、属性グループについて解説していきます。連載を読むに当たり、整形式のXMLに関して十分理解していることを前提とします。

[小野彩子,株式会社 四次元データ]

 前回は、XML Schemaで豊富に用意されているデータ型について解説しました。今回は「自分でデータ型を作る方法」について説明します。

基本データ型だけでは足りない

 それでは、発注データを表すXML文書を例に取り上げましょう。

<order>
  <orderItem>
    <id>4-8443-1780-6</id>
    <quantity>3</quantity>
  </orderItem>
</order>
リスト1 発注データXML

 発注データXMLは、ルート要素がorderのXML文書です。発注する商品の情報は、orderItem要素の内容(開始タグと終了タグの間)に記述されています。orderItem要素は子要素を2つ持ちます。商品番号を表すid要素と、発注数量を表すquantity要素です。

図1 発注データXMLのツリー構造 図1 発注データXMLのツリー構造

 さて、商品番号を表すid要素について見てみましょう。商品番号は「数字1個」の後に「-」(ハイフン)、さらに「数字4個」、「-」(ハイフン)、「数字4個」、「-」(ハイフン)、「数字1個」と続く形式です。ところで、「数字1個-数字4個-数字4個-数字1個」を表すデータ型は、基本データ型には存在しません。id要素の形式が適切かどうか検証するために、商品番号を表すデータ型を新たに作成しましょう。

データ型を作成する

 商品番号を表すデータ型は、以下のように作成します。

<xsd:simpleType name="idType">
  <xsd:restriction base="xsd:string">
    <xsd:pattern value="\d{1}-\d{4}-\d{4}-\d{1}"/>
  </xsd:restriction>
</xsd:simpleType>
リスト2 商品番号のスキーマ

データ型を宣言する「simpleType要素」

 新しいデータ型を宣言するためには、xsd:simpleType要素を使用します。

<xsd:simpleType name="idType">

 作成するデータ型の名前は、name属性で指定します。ここではidTypeという名前のデータ型を作成していますので、属性の値には「idType」と記述しましょう。

基本データ型を「制限」してデータ型を作成する

 xsd:simpleType要素の内容(開始タグと終了タグの間)に、「どんなデータ型なのか」記述します。

 XML Schemaでは、既存のデータ型に一定の「制限」を加えることで新たなデータ型を作成します。例えば、商品番号は「文字列」ですが、「数字1個-数字4個-数字4個-数字1個」というように形式が決まっています。このような場合、「文字列」を表す「xsd:string」をベースに、「“数字1個-数字4個-数字4個-数字1個”という形式のもの」という制限を加えて、新たなデータ型を作成します。

  <xsd:restriction base="xsd:string">

 xsd:simpleType要素の次に、「制限」を表すxsd:restriction要素を書きます。そして、「どのデータ型を基にしてデータ型を作成するのか」をbase属性の値に指定します。商品番号のデータ型は基本データ型の文字列型を基に作成しますので、base属性の値には「xsd:string」を指定します。

文字列の形式を指定するpattern要素

 文字列の形式を指定するためには、pattern要素を使用します。

    <xsd:pattern value="\d{1}-\d{4}-\d{4}-\d{1}"/>

 pattern要素は空要素ですが、value属性を持ちます。value属性の値には、商品番号データの形式を「正規表現」で記述します。正規表現とは、文字列の形式を指定するために使用される方法です。UNIX系のOSを使用している方にとってはおなじみでしょう。正規表現を使用してデータ型を作成できる、というのはXML Schemaの大きな利点です。正規表現は慣れていない方にはとっつきにくいかもしれませんが、非常に便利ですので習得することを強くお勧めします。正規表現についてここでは詳しく触れませんが、@ITにも解説記事がいろいろありますので、ぜひ参考にしてください。

 さて、商品番号は「数字1個-数字4個-数字4個-数字1個」という形式です。これを正規表現で表すと、以下のようになります。

\d{1}-\d{4}-\d{4}-\d{1}

 「\d」は数字を表します。後ろの「{1}」は、「直前で表現された文字が1個連なる」ことを意味します。よって、「\d{1}」は「数字1個」を表します。同様に「\d{4}」は、「数字4個」を表します。商品番号では、「数字1個」と「数字4個」の間にハイフンが入りますので、間にハイフンを記述します。商品番号の残りの部分も同様に記述していけば、正規表現の「\d{1}-\d{4}-\d{4}-\d{1}」が完成します。この正規表現をvalue属性の値に記述してください。

 最後に、xsd:restrictionおよびxsd:simpleTypeの終了タグを記述します。

  </xsd:restriction>
</xsd:simpleType>

 これで、商品番号を表すデータ型の完成です。

作ったデータ型を使う

 それでは、作成した商品番号データ型の要素を宣言してみましょう。宣言の方法は、簡単です。

<xsd:element name="id" type="idType" />

 xsd:element要素のtype属性の値に、作成した商品番号データ型の名前「idType」を記述するだけです。データ型の名前は、データ型を宣言しているxsd:simpleType要素のname属性の値です。「idType」の前に、名前空間接頭辞「xsd:」が付かないことに注意してください。idTypeは、XML Schemaの基本データ型ではありませんので、「XML Schema」を表す名前空間接頭辞「xsd:」を記述しません。

 発注データXMLのスキーマの全体は以下のようになります。

 1:<?xml version="1.0"?>
 2:<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 3:
 4:  <xsd:element name="order">
 5:    <xsd:complexType>
 6:      <xsd:sequence>
 7:        <xsd:element ref="orderItem" maxOccurs="10"/>
 8:      </xsd:sequence>
 9:    </xsd:complexType>
10:  </xsd:element>
11:
12:  <xsd:element name="orderItem">
13:    <xsd:complexType>
14:      <xsd:sequence>
15:        <xsd:element name="id" type="idType"/>
16:        <xsd:element name="quantity" type="xsd:integer"/>
17:      </xsd:sequence>
18:    </xsd:complexType>
19:  </xsd:element>
20:  
21:  <xsd:simpleType name="idType">
22:    <xsd:restriction base="xsd:string">
23:      <xsd:pattern value="\d{1}-\d{4}-\d{4}-\d{1}"/>
24:    </xsd:restriction>
25:  </xsd:simpleType>
26:  
27:</xsd:schema>
リスト3 発注データXMLのスキーマ1

値のリストを作成する

 発注できる商品番号があらかじめ決まっている場合があります。例えば、「4-8443-1780-6」「4-7741-1751-1」「4-7741-1684-1」のどれかの番号の商品しか発注できないとしましょう。このような場合、商品番号を表すデータ型は以下のようになります。

<xsd:simpleType name="idType">
  <xsd:restriction base="xsd:string">
    <xsd:enumeration value="4-8443-1780-6"/>
    <xsd:enumeration value="4-7741-1751-1"/>
    <xsd:enumeration value="4-7741-1684-1"/>
  </xsd:restriction>
</xsd:simpleType>

 まず、simpleType要素を使用して新しいデータ型を宣言します。データ型の名前は「idType」にします。名前は、name属性の値に記述します。また商品番号はすべて文字列ですので、xsd:string型を基に作成することにします。xsd:restriction要素を使用し、base属性の値には「xsd:string」を記述します。ここまでは前項と同じですね。

 決まったいくつかの値のみ指定可能なデータ型は、xsd:enumeration要素を使用して定義します。

    <xsd:enumeration value="4-8443-1780-6"/>

 値の数だけ、xsd:enumeration要素を記述します。商品番号は全部で3種類指定可能ですので、xsd:enumeration要素を3個書きます。xsd:enumeration要素は空要素ですが、value属性を持ちます。このvalue属性の値に、idTypeが取り得る値を記述します。ここでは「4-8443-1780-6」「4-7741-1751-1」「4-7741-1684-1」と記述していきます。これで、商品番号を表すデータ型の完成です。「4-8443-1780-6」「4-7741-1751-1」「4-7741-1684-1」以外の商品番号を指定した場合、検証時にエラーになります。

 1:<?xml version="1.0"?>
 2:<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 3:
 4:  <xsd:element name="order">
 5:    <xsd:complexType>
 6:      <xsd:sequence>
 7:        <xsd:element ref="orderItem" maxOccurs="10"/>
 8:      </xsd:sequence>
 9:    </xsd:complexType>
10:  </xsd:element>
11:
12:  <xsd:element name="orderItem">
13:    <xsd:complexType>
14:      <xsd:sequence>
15:        <xsd:element name="id" type="idType"/>
16:        <xsd:element name="quantity" type="xsd:integer"/>
17:      </xsd:sequence>
18:    </xsd:complexType>
19:  </xsd:element>
20:  
21:  <xsd:simpleType name="idType">
22:    <xsd:restriction base="xsd:string">
23:      <xsd:enumeration value="4-8443-1780-6"/>
24:      <xsd:enumeration value="4-7741-1751-1"/>
25:      <xsd:enumeration value="4-7741-1684-1"/>
26:    </xsd:restriction>
27: </xsd:simpleType>
28:  
29:</xsd:schema>
リスト4 発注データXMLのスキーマ2

数値の範囲を設定する

 今度は、発注数量を見てみましょう。発注数量を表すquantity要素は、基本データ型の整数xsd:integer型です。さらに、「一度に発注できる数量は10以下」という制限を付けましょう。そのためには、発注数量を表すデータ型を新たに作成する必要があります。発注数量を表すデータ型は以下のようになります。

<xsd:simpleType name="quantityType">
  <xsd:restriction base="xsd:integer">
    <xsd:minInclusive value="1"/>
    <xsd:maxInclusive value="10"/>
  </xsd:restriction>
</xsd:simpleType>

 まず、simpleType要素を使用して新しいデータ型を宣言します。データ型の名前を「quantityType」にします。名前は、name属性の値に記述します。発注数量を表すデータ型はxsd:integer型を基に作成することにします。xsd:restriction要素を使用し、base属性の値には「xsd:integer」を記述します。

 数値の範囲を制限するには、xsd:minInclusive要素xsd:maxInclusive要素を使用します。

    <xsd:minInclusive value="1"/>
    <xsd:maxInclusive value="10"/>

 xsd:minInclusive要素は、数値の下限値を指定するために使用します。xsd:minInclusive要素のvalue属性の値に下限値を指定します。ここではvalue属性の値は「1」ですので、発注数量は「1以上の整数」と規定していることになります。同様に、xsd:maxInclusive要素は、数値の上限値を指定するために使用します。xsd:maxInclusive要素のvalue属性の値に上限値を指定します。ここではvalue属性の値は「10」ですので、発注数量は「10以下の整数」と規定していることになります。xsd:restriction要素とxsd:simpleType要素の終了タグを記述すれば、「1以上10以下の整数」を表すquantityTypeデータ型の完成です。

 数値の範囲を指定する要素は、ほかにもxsd:minExclusive要素xsd:maxExclusive要素があります。xsd:minInclusive、xsd:maxInclusive要素と同様に、数値の範囲を規定するための要素ですが、境界値の取り扱い方が異なります。

    <xsd:minInclusive value="1"/>

 例えば、xsd:minInclusive要素を使用した場合、value属性に指定した値「1」は有効な値になります。「1以上」を表しています。

    <xsd:minExclusive value="1"/>

 xsd:minExclusive要素を使用した場合、value属性に指定した値は範囲に含まれません。これは「1より大きい数値」を表します。このような指定があるデータ型では、1を記述すると検証時にエラーになります。

 最後に、発注データ全体のスキーマです。

 1:<?xml version="1.0"?>
 2:<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 3:
 4:  <xsd:element name="order">
 5:    <xsd:complexType>
 6:      <xsd:sequence>
 7:        <xsd:element ref="orderItem" maxOccurs="10"/>
 8:      </xsd:sequence>
 9:    </xsd:complexType>
10:  </xsd:element>
11:
12:  <xsd:element name="orderItem">
13:    <xsd:complexType>
14:      <xsd:sequence>
15:        <xsd:element name="id" type="idType"/>
16:        <xsd:element name="quantity" type="quantityType"/>
17:      </xsd:sequence>
18:    </xsd:complexType>
19:  </xsd:element>
20:  
21:  <xsd:simpleType name="idType">
22:    <xsd:restriction base="xsd:string">
23:      <xsd:enumeration value="4-8443-1780-6"/>
24:      <xsd:enumeration value="4-7741-1751-1"/>
25:      <xsd:enumeration value="4-7741-1684-1"/>
26:    </xsd:restriction>
27:  </xsd:simpleType>
28:  
29:  <xsd:simpleType name="quantityType">
30:    <xsd:restriction base="xsd:integer">
31:      <xsd:minInclusive value="1"/>
32:      <xsd:maxInclusive value="10"/>
33:    </xsd:restriction>
34:  </xsd:simpleType>
35:
36:</xsd:schema>
リスト5 発注データXMLのスキーマ完成形


 今回は基本データ型を基にして、新しいデータ型を定義する方法を解説しました。とうとう次回で最終回です。最終回では、属性について解説します。(次回に続く)

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

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

メールマガジン登録

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