連載
» 2004年04月20日 10時00分 公開

XMLテクニック集(12):XML Schemaで値の有効範囲を定義する (2/3)

[山田祥寛,@IT]

XML Schemaで複数の型を結合する

アイコン

2つ以上の異なる制約条件を1つの要素・属性に対して適用するには、<xsd:restriction>要素と<xsd:union>要素を組み合わせ、2段階の手順を踏んで定義します。

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

 HTMLにおける<body>タグを想定してみましょう。例えば、背景色を白に設定したいと思った場合、

<body bgcolor="#FFffFF">


のようにRGB形式の文字列で指定することも、

<body bgcolor="White">


のように色名で指定することも可能です。

 このように同じ属性であっても、異なる型(体系)で値を指定できるケースが少なくありません。このような場合にも、XML Schemaでは<xsd:union>要素を用いることで、2つ以上の異なる制約条件を1つの要素・属性に対して適用できます。

 ここでは、出版社を表す<publish>要素を出版社番号(整数型)、または、出版者名(文字列型)で指定できるようにスキーマを定義してみます。なお、対象となるXML文書については、別稿「XML Schemaで文字列パターンを定義する」で用いたbook.xmlを参照してください。

books_union.xsd

<?xml version="1.0" encoding="Shift_JIS" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <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:simpleType name="pub_number">
    <xsd:restriction base="xsd:integer">
      <xsd:enumeration value="1" />
      <xsd:enumeration value="2" />
      <xsd:enumeration value="3" />
      <xsd:enumeration value="4" />
      <xsd:enumeration value="5" />
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:simpleType name="pub_string">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="@IT" />
      <xsd:enumeration value="翔泳社" />
      <xsd:enumeration value="技術評論社" />
      <xsd:enumeration value="日経BP社" />
      <xsd:enumeration value="秀和システム" />
    </xsd:restriction>
  </xsd:simpleType>

  <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">
        <xsd:simpleType>
          <xsd:union>
            <xsd:simpleType>
              <xsd:restriction base="pub_number" />
            </xsd:simpleType>
            <xsd:simpleType>
              <xsd:restriction base="pub_string" />
            </xsd:simpleType>
          </xsd:union>
        </xsd:simpleType>
      </xsd:element>

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


 ここでは、大きく2つのブロックに分けて理解する必要があります。

(1)結合する元となるデータ型を定義

 まずは、結合する元となる2つのデータ型を定義しなければなりません。すなわち、以下の部分です。

<xsd:simpleType name="pub_number">
  <xsd:restriction base="xsd:integer">
    ……中略……
  </xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="pub_string">
  <xsd:restriction base="xsd:string">
    ……中略……
  </xsd:restriction>
</xsd:simpleType>


 ここでは、整数型をベースとした1〜5の値から構成されるpub_number型、文字列型をベースとした列挙値から構成されるpub_string型を規定しています。

(2)既存のデータ型を結合する

 次に、これらのデータ型(単純型)を具体的な要素にひも付けると同時に、結合する必要があります。それが、以下の部分です。

<xsd:element name="published">
  <xsd:simpleType>
    <xsd:union>
      <xsd:simpleType>
        <xsd:restriction base="pub_number" />
      </xsd:simpleType>
      <xsd:simpleType>
        <xsd:restriction base="pub_string" />
      </xsd:simpleType>
    </xsd:union>
  </xsd:simpleType>
</xsd:element>


 <xsd:union>要素で2つのデータ型を結合し、<published>要素の定義としてセットしています。これによって、<published>要素を整数値、もしくは文字列で指定することが可能になるというわけです。

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


Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

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

メールマガジン登録

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