XSDの例
この章では、XMLスキーマの作成方法について説明します。また、スキーマはさまざまな方法で記述できることも学びます。
XMLドキュメント
「shiporder.xml」と呼ばれるこのXMLドキュメントを見てみましょう。
<?xml version="1.0" encoding="UTF-8"?>
<shiporder orderid="889923"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shiporder.xsd">
<orderperson>John Smith</orderperson>
<shipto>
<name>Ola Nordmann</name>
<address>Langgt 23</address>
<city>4000 Stavanger</city>
<country>Norway</country>
</shipto>
<item>
<title>Empire Burlesque</title>
<note>Special Edition</note>
<quantity>1</quantity>
<price>10.90</price>
</item>
<item>
<title>Hide your heart</title>
<quantity>1</quantity>
<price>9.90</price>
</item>
</shiporder>
上記のXMLドキュメントは、「orderid」と呼ばれる必須属性を含むルート要素「shiporder」で構成されています。「shiporder」要素には、「orderperson」、「shipto」、「item」の3つの異なる子要素が含まれています。「item」要素は2回表示され、「title」、オプションの「note」要素、「quantity」、および「price」要素が含まれています。
上記の行:xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"は、このドキュメントをスキーマに対して検証する必要があることをXMLパーサーに通知します。次の行:xsi:noNamespaceSchemaLocation = "shiporder.xsd"は、スキーマが存在する場所を指定します(ここでは、「shiporder.xml」と同じフォルダーにあります)。
XMLスキーマを作成する
次に、上記のXMLドキュメントのスキーマを作成します。
まず、「shiporder.xsd」という名前の新しいファイルを開きます。スキーマを作成するには、XMLドキュメントの構造をたどり、見つけた各要素を定義するだけです。標準のXML宣言から始め、その後にスキーマを定義するxs:schema要素が続きます。
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
...
</xs:schema>
上記のスキーマでは、標準の名前空間(xs)を使用しており、この名前空間に関連付けられているURIは、http://www.w3.org/2001/XMLSchemaの標準値を持つスキーマ言語定義です。
次に、「shiporder」要素を定義する必要があります。この要素には属性があり、他の要素が含まれているため、複合型と見なします。「shiporder」要素の子要素は、サブ要素の順序付けられたシーケンスを定義するxs:sequence要素で囲まれています。
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
...
</xs:sequence>
</xs:complexType>
</xs:element>
次に、「orderperson」要素を単純型として定義する必要があります(属性やその他の要素が含まれていないため)。タイプ(xs:string)には、事前定義されたスキーマデータ型を示すXMLスキーマに関連付けられた名前空間プレフィックスがプレフィックスとして付けられます。
<xs:element name="orderperson" type="xs:string"/>
次に、複合タイプの2つの要素「shipto」と「item」を定義する必要があります。まず、「shipto」要素を定義します。
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
スキーマを使用すると、maxOccurs属性とminOccurs属性を使用して要素の発生の可能性のある数を定義できます。maxOccursは要素の最大発生数を指定し、minOccursは要素の最小発生数を指定します。maxOccursとminOccursの両方のデフォルト値は1です!
これで、「item」要素を定義できます。この要素は、「shiporder」要素内に複数回表示される可能性があります。これは、「item」要素のmaxOccurs属性を「unbounded」に設定することで指定されます。これは、作成者が望むだけ「item」要素が出現する可能性があることを意味します。「note」要素はオプションであることに注意してください。minOccurs属性をゼロに設定することでこれを指定しました。
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string" minOccurs="0"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:element>
これで、「shiporder」要素の属性を宣言できます。これは必須属性であるため、use = "required"を指定します。
注:属性宣言は常に最後に来る必要があります:
<xs:attribute name="orderid" type="xs:string" use="required"/>
「shiporder.xsd」と呼ばれるスキーマファイルの完全なリストは次のとおりです。
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string" minOccurs="0"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="orderid" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
スキーマを分割する
以前の設計方法は非常に単純ですが、ドキュメントが複雑な場合、読み取りと保守が困難になる可能性があります。
次の設計方法は、最初にすべての要素と属性を定義し、次にref属性を使用してそれらを参照することに基づいています。
スキーマファイル( "shiporder.xsd")の新しいデザインは次のとおりです。
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- definition of simple elements -->
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
<!-- definition of attributes -->
<xs:attribute name="orderid" type="xs:string"/>
<!-- definition of complex elements -->
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element ref="address"/>
<xs:element ref="city"/>
<xs:element ref="country"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:element ref="title"/>
<xs:element ref="note" minOccurs="0"/>
<xs:element ref="quantity"/>
<xs:element ref="price"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element ref="orderperson"/>
<xs:element ref="shipto"/>
<xs:element ref="item" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute ref="orderid" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
名前付きタイプの使用
3番目の設計メソッドは、クラスまたはタイプを定義します。これにより、要素定義を再利用できます。これは、simpleTypes要素とcomplexTypes要素に名前を付けてから、要素のtype属性を介してそれらを指すことによって行われます。
スキーマファイル( "shiporder.xsd")の3番目のデザインは次のとおりです。
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="stringtype">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="inttype">
<xs:restriction base="xs:positiveInteger"/>
</xs:simpleType>
<xs:simpleType name="dectype">
<xs:restriction base="xs:decimal"/>
</xs:simpleType>
<xs:simpleType name="orderidtype">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{6}"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="shiptotype">
<xs:sequence>
<xs:element name="name" type="stringtype"/>
<xs:element name="address" type="stringtype"/>
<xs:element name="city" type="stringtype"/>
<xs:element name="country" type="stringtype"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="itemtype">
<xs:sequence>
<xs:element name="title" type="stringtype"/>
<xs:element name="note" type="stringtype" minOccurs="0"/>
<xs:element name="quantity" type="inttype"/>
<xs:element name="price" type="dectype"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="shipordertype">
<xs:sequence>
<xs:element name="orderperson" type="stringtype"/>
<xs:element name="shipto" type="shiptotype"/>
<xs:element name="item" maxOccurs="unbounded" type="itemtype"/>
</xs:sequence>
<xs:attribute name="orderid" type="orderidtype" use="required"/>
</xs:complexType>
<xs:element name="shiporder" type="shipordertype"/>
</xs:schema>
制限要素は、データ型がW3CXMLスキーマ名前空間データ型から派生していることを示します。したがって、次のフラグメントは、要素または属性の値が文字列値でなければならないことを意味します。
<xs:restriction base="xs:string">
制限要素は、要素に制限を適用するためによく使用されます。上記のスキーマの次の行を見てください。
<xs:simpleType name="orderidtype">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]{6}"/>
</xs:restriction>
</xs:simpleType>
これは、要素または属性の値が文字列である必要があり、行に正確に6文字である必要があり、それらの文字が0から9までの数字である必要があることを示します。