XML Schemaで空要素を定義する:XMLテクニック集(13)(2/3 ページ)
要素の値を取りあえずブランクにしておきたいケースでは、対象の要素定義に「nillable="true"」を記述し、XML文書側で「xsi:nil="true"」と明示的に宣言します。これでパーサの検証時にnull値が許容されます。
別稿「XML Schemaで空要素を定義する」では、空要素を規定するための方法について紹介しました。しかし、これはあらかじめ要素が空であることが「決まっている」場合の手法です。例えば、書籍情報などでまだ発刊日が決まっていない、価格が決まっていないなどの理由で、取りあえずデータをブランクのままにしておきたいケースもあります。
文字列データの場合、空文字列をセットしてもパーサの検証に引っ掛かることはありませんが、数値や日付データの場合、ブランクは妥当性エラーです。このような場合には、どのようにしたらよいのでしょう。
以下では、暫定的なnullデータに対処する2つの方法を紹介します。対象となるXML文書は、別稿「XML Schemaで文字列パターンを定義する」で用いたbooks.xmlを参照してください。
[books_nullable_pre.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="nullable">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="price_int">
<xsd:restriction base="xsd:positiveInteger">
<xsd:maxInclusive value="10000" />
<xsd:minInclusive value="1000" />
</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" type="xsd:string" />
<xsd:element name="price">
<xsd:simpleType>
<xsd:union>
<xsd:simpleType>
<xsd:restriction
base="nullable" />
</xsd:simpleType>
<xsd:simpleType>
<xsd:restriction
base="price_int" />
</xsd:simpleType>
</xsd:union>
</xsd:simpleType>
</xsd:element>
<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> |
まず1つ目の例は、別稿「XML Schemaで複数の型を結合する」で紹介した、<xsd:union>要素を用いる手法です。要素に対して、列挙値として空文字列を含むデータ型と本来規定すべきデータ型とを結合したうえで定義します。
ただし、この手法は記述が冗長であるうえ、常に空文字列を許す定義となってしまい、厳密に制約するという観点からはあまり好ましくありません。
そこで登場するのが、以下の手法です。
[books_nullable.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:complexType name="book_type">
<xsd:sequence>
<xsd:element name="title" type="xsd:string" />
<xsd:element name="author" type="xsd:string" />
<xsd:element name="published" type="xsd:string" />
<xsd:element name="price" type="xsd:positiveInteger"
nillable="true"/>
<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> |
対象の要素定義に「nillable="true"」という一文を追記しています。これによって、<price>要素に対してnull値が許されるようになりました。ただし、無条件にnullを許すというわけではありません。
元となるbooks.xmlを見てみましょう。
[books.xml]
<?xml version="1.0" encoding="Shift_JIS" ?>
<atit:books xmlns:atit="urn:bookList" name="書籍情報一覧"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<book isbn="ISBN4-7981-0189-3">
<title>10日でおぼえるJSP/サーブレット入門教室</title>
<author>Y.Yamada</author>
<published>翔泳社</published>
<price xsi:nil="true"></price>
<publishDate>2002-05-17</publishDate>
<category>JSP&サーブレット</category>
<keywords>JSP サーブレット Tomcat J2SE</keywords>
</book>
</atit:books> |
<price>要素に「xsi:nil="true"」と明示的に宣言した場合にのみ<price>要素にnull値のセットを許すのです。xsi:nil属性が指定されていない場合、<price>要素にnullを指定することは許されません。なお、xsi:nil属性を使用する場合には、必ずxsi名前空間の宣言を行うのを忘れないようにしてください。
これによって、より明示的なnullデータの管理を行うことができるというわけです。
実際に、妥当性検証を行いたい場合には、別稿「XML SchemaでXML文書の妥当性を検証する」のサンプルを参考にするとよいでしょう。変更個所は、XMLSchemaCache.addメソッドの第2引数(XML Schemaのファイル名)のみです。スキーマ文書を書いてみるだけでは、スキーマ文書そのものの妥当性を判断できませんが、パーサの処理を介することでスキーマの正否を確認できます。
Copyright © ITmedia, Inc. All Rights Reserved.