Powered by SmartDoc

XML Schema (2)

単純型と複合型

XML Schemaでは、大きく分けると「単純型」と「複合型」という、2つの型があります。この2つの型の概要をご紹介しましょう。

単純型

内容がテキストからなる型を「単純型」と呼びます。

XML Schemaには、文字列や整数など、あらかじめいくつかのデータ型が組み込まれています。

また、単純型のうち、データの「派生」という仕組みを使って新たなデータ型を定義するときには、simpleType要素を用います。詳細は次回に解説します。

<xsd:simpleType>〜 </xsd:simpleType>

複合型

要素の内容に、要素や属性を含むものを「複合型」と呼びます。複合型はcomplexType要素を用いて指定します。

<xsd:complexType>〜 </xsd:complexType>

XML Schema 組み込みのデータ型

主なデータ型

XML Schemaでは、要素の内容に「データ型」を指定できます。例えば、「この要素の内容には整数しか入らない」といったことが指定できるのです。

このため、XML Schemaには、あらかじめいくつかのデータ型が用意されています。代表的なデータ型を示しましょう。

string
文字列
boolean
論理型(trueかfalse / 1か0)
integer
整数
nonNegativeInteger
0以上の整数
nonPositiveInteger
0以下の整数
float
単精度浮動小数
double
倍精度浮動小数
date
日付(2004-05-21)
time
時刻(10:40:00-09:00)

データ型を利用した例

データ型を利用した例を示しましょう。element要素のtype属性にデータ型を指定します。

<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.wakhok.ac.jp/~tomoharu/students"
            xmlns:st="http://www.wakhok.ac.jp/~tomoharu/students">
    <xsd:element name="number" type="xsd:integer"/>
</xsd:schema>

名前空間などの属性を除くと、次のようになります。

<?xml version="1.0"?>
<xsd:schema>
    <xsd:element name="number" type="xsd:integer"/>
</xsd:schema>

このXML Schemaでは、この部分でnumberという要素の内容がinteger (整数)であることを示しています。

    <xsd:element name="number" type="xsd:integer"/>

このXML Schemaに対応するXMLインスタンスは、次のようなものです。

<?xml version="1.0"?>
<st:number xmlns:st="http://www.wakhok.ac.jp/~tomoharu/students"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.wakhok.ac.jp/~tomoharu/students \
    sample02.xsd">
        123
</st:number>

名前空間を外したものも示しましょう。

<?xml version="1.0"?>
<st:number>
        123
</st:number>

XSVを使って、このXMLインスタンスを検証してみましょう。

number要素の内容が123という整数であるため、このXMLインスタンスはXML Schemaに適合していることになります。

次のようなXMLインスタンスは、number要素の内容が整数でないため、XML Schemaに適合していません。

<?xml version="1.0"?>
<st:number>
        abcdefg
</st:number>

複合型 (1)

複合型

「複合型」とは、要素の内容に、要素や属性を含むものです。

まず、次のXMLインスタンスをご覧ください。

<?xml version="1.0"?>
<st:student xmlns:st="http://www.wakhok.ac.jp/~tomoharu/students"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.wakhok.ac.jp/~tomoharu/students \
    sample03.xsd">
    <st:familyName>安藤</st:familyName>
    <st:givenName>友晴</st:givenName>
</st:student>

名前空間の指定を外すと、次のようになります。

<?xml version="1.0"?>
<st:student>
    <st:familyName>安藤</st:familyName>
    <st:givenName>友晴</st:givenName>
</st:student>

student要素の中に、familyName要素とgivenName要素が含まれています。

このような型が、複合型となります。

complexType 要素

それでは、このXMLインスタンスの元となるXML Schemaの文書について見てみましょう。

複合型はcomplexType要素を用いて指定します。student要素の子要素に、complexType要素があるのがわかるでしょう。

<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            elementFormDefault="qualified"
            targetNamespace="http://www.wakhok.ac.jp/~tomoharu/students"
            xmlns:st="http://www.wakhok.ac.jp/~tomoharu/students">
    <xsd:element name="student">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="familyName" type="xsd:string" />
                <xsd:element name="givenName" type="xsd:string" />
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

sequence 要素

complexType要素の子要素には、sequence要素が出てきています。

        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="familyName" type="xsd:string" />
                <xsd:element name="givenName" type="xsd:string" />
            </xsd:sequence>
        </xsd:complexType>

このsequence要素は、項目が順番に出現することを表します。この場合は、familyName要素が出てきてから、givenName要素が出てくることになります。順番の変更や、要素の省略は許されません。

次の例は、このXML Schemaに適合するXMLインスタンス(の一部)です。

<st:student>
    <st:familyName>安藤</st:familyName>
    <st:givenName>友晴</st:givenName>
</st:student>

student要素の子要素として、familyName要素が最初に登場し、その後にgivenName要素が現れています。

次は、このXML Schemaに適合しない例です。

<st:student>
    <st:givenName>友晴</st:givenName>
    <st:familyName>安藤</st:familyName>
</st:student>

givenNameとfamilyNameの順序が逆転しています。

次の例も、XML Schemaに適合しません。

<st:student>
    <st:familyName>安藤</st:familyName>
</st:student>

givenName要素がないからです。

グローバル要素・ローカル要素と名前空間

先に見たこのXML Schemaについて、もう一度考えてみます。

<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            elementFormDefault="qualified"
            targetNamespace="http://www.wakhok.ac.jp/~tomoharu/students"
            xmlns:st="http://www.wakhok.ac.jp/~tomoharu/students">
    <xsd:element name="student">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="familyName" type="xsd:string" />
                <xsd:element name="givenName" type="xsd:string" />
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

student要素の要素のように、schema要素の直下で定義されている要素のことを「グローバル要素」と呼びます。また、familyName要素やgivenName要素のように、complexType要素の中で定義されている要素のことを「ローカル要素」と呼びます。

さて、XML Schemaのデフォルトの設定では、ローカル要素に名前空間が適用されません。従って、デフォルトの設定のままでは、次のようなXMLインスタンスは間違いとなります。

<st:student>
    <st:familyName>安藤</st:familyName>
    <st:givenName>友晴</st:givenName>
</st:student>

正しくは、名前空間をつけないようにする必要があります。

<st:student>
    <familyName>安藤</familyName>
    <givenName>友晴</givenName>
</st:student>

そこで、schema要素のElementFormDefault属性の値を"qualified"にすることで、familyName要素やgivenName要素に名前空間を付けることができるようになるのです。

<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            elementFormDefault="qualified"
            targetNamespace="http://www.wakhok.ac.jp/~tomoharu/students"
            xmlns:st="http://www.wakhok.ac.jp/~tomoharu/students">
    ......
</xsd:schema>

これで、子要素にも名前空間を使えるようになります。

<st:student>
    <st:familyName>安藤</st:familyName>
    <st:givenName>友晴</st:givenName>
</st:student>

ref 属性

このXML Schemaは、次のようにも書けます。

<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.wakhok.ac.jp/~tomoharu/students"
            xmlns:st="http://www.wakhok.ac.jp/~tomoharu/students">
    <xsd:element name="student">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="st:familyName" />
                <xsd:element ref="st:givenName" />
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name="familyName" type="xsd:string" />
    <xsd:element name="givenName" type="xsd:string" />
</xsd:schema>

先の例との違いは、次の点となります。

            <xsd:sequence>
                <!-- 具体的な定義は ref 属性で指定したところで -->
                <xsd:element ref="st:familyName" />
                <xsd:element ref="st:givenName" />
            </xsd:sequence>
        ......
    <!-- familyName と givenName の具体的な定義 -->
    <xsd:element name="familyName" type="xsd:string" />
    <xsd:element name="givenName" type="xsd:string" />

元のXML Schemaでは、familyNameとgivenNameの定義がsequence要素の直下にありました。この例ではfamilyNameとgivenNameにref属性があり、それぞれの要素の具体的な定義は、schema要素の直下に移動しているのです。

ref属性を使うことによって、XML Schemaの階層が深くなっても、わかりやすいSchemaを記述できます。

また、ref属性を使うことによって、complexType要素の中で定義されている要素も、グローバル要素にすることができます。その結果、ElementFormDefault属性を付け加えなくても、名前空間が利用できるようになるのです。

参考文献・URL

Extensible Markup Language (XML) 1.0 (Third Edition)
W3C XML Schema