XML Schemaでは、大きく分けると「単純型」と「複合型」という、2つの型があります。この2つの型の概要をご紹介しましょう。
内容がテキストからなる型を「単純型」と呼びます。
XML Schemaには、文字列や整数など、あらかじめいくつかのデータ型が組み込まれています。
また、単純型のうち、データの「派生」という仕組みを使って新たなデータ型を定義するときには、simpleType要素を用います。詳細は次回に解説します。
<xsd:simpleType>〜 </xsd:simpleType>
要素の内容に、要素や属性を含むものを「複合型」と呼びます。複合型はcomplexType要素を用いて指定します。
<xsd:complexType>〜 </xsd:complexType>
XML Schemaでは、要素の内容に「データ型」を指定できます。例えば、「この要素の内容には整数しか入らない」といったことが指定できるのです。
このため、XML Schemaには、あらかじめいくつかのデータ型が用意されています。代表的なデータ型を示しましょう。
データ型を利用した例を示しましょう。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>
「複合型」とは、要素の内容に、要素や属性を含むものです。
まず、次の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要素が含まれています。
このような型が、複合型となります。
それでは、この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>
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>
この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属性を付け加えなくても、名前空間が利用できるようになるのです。