XML Schema達人への道
基礎1:宣言と型定義
(株)日本ユニテック
奥井 康弘
お詫び
[xsd:allの指定]の部分で誤りがあり、2003年2月3日に訂正いたしました。読者の方々には大変ご迷惑をおかけいたしました。内容をご確認ください。 |
<この記事はDigital
Xpress 2001 Vol.5(10-11月号)に掲載されたものです>
さて、今回から本格的にXML Schema(スキーマ)のお話をいたしましょう。このXML Schema、今年の5月にW3Cの正式な勧告になったことで、今後実装が進み利用する機会も出てくると考えられます。「難しい」と言われるXML
Schemaですが、ひとつひとつ勉強を積み重ねて行けば攻略も可能です!!さあ、みんなで一緒にXML Schemaを勉強しましょう!
XML Schemaのどこが難しいの?
よくXML Schemaは「難しい」と言われます。それには2つの理由があると考えられます。
● 規格書を読んでも訳がわからない
● データ型の継承の考え方について行けない
この2点は、最初の段階では「誰かがやさしく教えてあげること」「型の継承など理論的な背景はあまり意識せずに、とにかく用意されているビルトインデータ型を使って済ませること」で済ませて「XML
Schemaアレルギー」を取り除けば十分ついていけます。
そもそも今のXML Schemaって、実現できることは何かと考えればそんなに対したことをやっているわけじゃありません。名前空間を意識していることを除けば、DTDに毛の生えた程度の内容です。(といって、その重要性を軽視するわけではありませんので念のため)そう!あなたもXML
Schemaの達人になれるのです!!
では、スキーマの書き方を順に説明しましょう。
スキーマ文書
XML SchemaでXMLのデータ構造を定義する記述はスキーマ文書と呼ばれます。これは、次のように書きます。
スキーマ文書の書き方
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
スキーマ指定
</xsd:schema>
お分かりのようにスキーマ文書自体、XMLのタグを使って書きます。スキーマ指定のための要素を見分けるためにXML Schemaの名前空間を使います。名前空間URIは、"http://www.w3.org/2001/XMLSchema"です。名前空間接頭辞としてはxsdを使っていますが、これは別のものでも構いません。
DTDは、タグではなく、DTD独自の文法を持っていました。XML Schemaのスキーマ文書は、XSLTなどと同様、XML文法に従っていますので、XML
Schemaの処理プログラムはXMLプロセッサを文法解析に使用することができます。まあ、これは開発者にとってのメリットで、ユーザーにはそれほど大きな影響はありませんが..
データ構造を分析する
では、ここで次のようなデータをXMLで表すことを考え、その構造をXML Schemaで表現することにしましょう。
<?xml version="1.0"?>
<menu>
<item><name>カツカレー</name><price>500</price></item>
<item><name>ハヤシライス</name><price>500</price></item>
<item><name>ビーフストロガノフ</name><price>500</price></item>
</menu>
これは、ツリー構造としては、次のような構造をしています。
まず、これをDTDで表現してみましょう。次のようになります。
<!ELEMENT menu (item+)>
<!ELEMENT item (name, price)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT price (#PCDATA)>
要素を宣言する
DTDにおける1つ1つの要素型宣言はXML Schemaの要素宣言に置き換えることができます。menu要素の宣言をXML
Schemaで書いてみましょう。XML Schemaではこれを要素宣言(element declaration)と呼びます。
(DTD)
<!ELEMENT menu (item+)>
↓
(XML Schema)
<xsd:element name="menu">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="item"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
なんと、1行の指定が7行になってしまいました。でも、これはXMLのタグで表現する場合には仕方のないことでしょうね。気を取り直して、要素宣言の方法を分析してみましょう。まず、宣言する要素自体はxsd:elementで指定しています。要素名はname属性に書きます。
要素の内容を定義する
次は、その要素の中身の定義です。item要素を1回以上無限回繰り返すわけですが、それはxsd:elementの中のxsd:complexTypeで行っています。これは型定義(type
dfinition)と呼ばれます。型は、要素がどんな順番で何回現れるかを指定することになります。
順番はxsd:sequenceで表現します。その中に順番に並ぶ要素をこれまたxsd:elementを使って並べます。このxsd:elementは親の要素宣言としてのxsd:elementとは意味が違って内容モデルに出現する要素を表すためのものです。どんな要素が現れるかはref属性で指定します。
さて、次は回数です。これはxsd:elementの中のminOccurs属性とmaxOccurs属性で指定します。それぞれ、最低出現回数と最高出現回数の指定です。共にデフォルト値が1なので一回だけ出現する要素にはこれらの属性を書く必要はありません。今考えているのは1回以上無限回という指定なので、minOccurs属性は省略し、maxOccurs属性で「無限回」を表す"unbounded"というキーワードを使用します。
DTDでは、「1回のみ」「0回か1回」「0回以上無限回」「1回以上無限回」の指定はできましたが、「m回以上n回以下」という指定はできませんでした。これはXML
Schemaにおける特徴の1つです。「m回以上n回以下」という指定ができるということは、最小回数と最大回数を同じ数にすれば「ちょうどm回出現」という指定も行えるということです。
XML Schemaの特徴
要素の出現回数を最小回数と最大回数で指定できる
順番の指定としては、今は「順に出現」というxsd:sequenceを説明しましたが、「どちらか一方が出現」というxsd:choiceという指定と「順序は問わず0回か1回出現」というxsd:allという指定が用意されています。
[DTDと比較したxsd:sequenceの指定]
(DTD)
<!ELEMENT x (a, b)>
↓
(XML Schema)
<xsd:element name="x">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="a"/>
<xsd:element ref="b"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
[DTDと比較したxsd:choiceの指定]
(DTD)
<!ELEMENT x (a|b)>
↓
(XML Schema)
<xsd:element name="x">
<xsd:complexType>
<xsd:choice>
<xsd:element
ref="a"/>
<xsd:element
ref="b"/>
</xsd:choice>
</xsd:complexType>
</xsd:element>
[xsd:allの指定]
(XML Schema)
<xsd:element name="x">
<xsd:complexType>
<xsd:all>
<xsd:element ref="a"/>
<xsd:element ref="b"/>
</xsd:all>
</xsd:complexType>
</xsd:element>
このxsd:allはXMLには対応するものがありませんが、「順序は問わず指定された要素を1回書く」ということは、上記のスキーマ指定の場合次のようなXMLインスタンスが書けることになります。
<x>
<a>……..</a>
<b>……..</b>
</x>
<x>
<b>……..</b>
<a>……..</a>
</x>
[xsd:allの指定]を次のようにしてxsd:elementでminOccurs="0"を指定すると、「順序は問わず0回か1回出現」ということで、下記の3つのバリエーションも可能になります。
(XML Schema)
<xsd:element name="x">
<xsd:complexType>
<xsd:all>
<xsd:element
ref="a" minOccurs="0"/>
<xsd:element
ref="b" minOccurs="0"/>
</xsd:all>
</xsd:complexType>
</xsd:element>
<x>
<a>……..</a>
</x>
<x>
<b>……..</b>
</x>
<x></x>
ではitem要素の宣言に移りましょう。item要素は、内容としてname要素とprice要素が順番に出現します。そしてそれぞれ一回だけ出現します。つまり、次のようなスキーマ指定となります。
(DTD)
<!ELEMENT item (name, price)>
↓
(XML Schema)
<xsd:element name="item">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="name"/>
<xsd:element ref="price"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
ここまでに説明した、内容に要素を持つ場合の要素宣言は次のような書き方をします。
内容に要素を持つ場合の要素宣言の書き方
●xsd:elementのname属性に要素名を書く
●xsd:elementの間にxsd:complexTypeを書く
●xsd:complexTypeの中に内容となる要素をxsd:sequence、xsd:choice、xsd:allで囲んだxsd:elementを使って参照する
●子要素の回数はxsd:elementのminOccurs属性とmaxOccurs属性で最小回数と最大回数で指定する(デフォルト値は両方とも"1"回)
>>続いて「文字列だけを持つ場合の要素宣言」について見てみましょう。
関連サービス
XMLスキーマの策定、作成業務
関連キーワード: XMLスキーマ
関連キーワード: 型定義
|