複数要素を定義する4つの基本形を覚えよう:SEのためのXML Schema入門(2)
この連載では、XML Schemaについて解説します。簡単なXMLの構造をXML Schemaにより記述できるようになることを目標に、XML Schemaの概要、要素・属性の定義、Complex TypeやSimple Type、属性グループについて解説していきます。連載を読むに当たり、整形式のXMLに関して十分理解していることを前提とします。
子要素を持つ要素のスキーマ定義
前回「簡単なXML Schemaから始めよう」は、ルート要素が1つだけの簡単なXMLの構造をXML Schemaで記述しました。今回は複数の要素からなるXMLのXML Schemaでの定義について説明します。
まずは、顧客データを表すXML文書(リスト1)のスキーマをXML Schemaで書いてみましょう。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
リスト1の顧客XMLは、要素が3つあるXML文書です。XMLの構造は、以下のようになっています。
要素名 | 特性 |
---|---|
customer | ルート要素。属性を持たない name、addressの2つの子要素を持つ name、addressの順に出現する |
name address |
子要素、属性を持たない 内容には文字列のみ含まれる |
顧客XMLのスキーマをXML Schemaで表すと、リスト2のようになります。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
単純型と複雑型
customer要素は子要素を持ちます。子要素を持つ要素はXML Schemaでどのように宣言すればよいのでしょうか? 「要素がどのような子要素や属性を持つのか」「属性がどのような値を持つのか」を表すために、XML Schemaではデータ型を使用します。データ型には2種類あります。
- 複雑型
子要素または属性を持つ要素のデータ型 - 単純型
子要素および属性を持たない要素のデータ型、あるいは属性値のデータ型
要素は複雑型か単純型かによって、宣言する方法が異なります。customer要素のように子要素を持つ要素は複雑型です。複雑型の要素を宣言する方法について見ていきましょう。
XML宣言、xsd:schema要素を記述した後、3行目よりxsd:element要素を使用してcustomer要素を宣言します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
name属性の値には、要素名「customer」を指定します。
複雑型を表す「complexType」
複雑型の要素を宣言する場合は、xsd:complexType要素を使用します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
xsd:complexType要素はxsd:element要素の直下に記述します。
子要素の順番を指定する「sequence」
xsd:complexType要素の内容(開始タグと終了タグの間)に、customer要素がどのような子要素を持つのか、記述します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
xsd:sequence要素は子要素の順番を指定するXML Schemaの要素です。xsd:sequence要素の内容では、name、addressの順番に要素を宣言しています。これは、「顧客XMLでは、name要素、address要素の順に書かなければならない」ことを表しています。
子要素を宣言する
name、addressなどの子要素は、xsd:sequence要素の内容(開始タグと終了タグの間)で宣言します。まず、xsd:element要素を使って、name要素を宣言します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
name属性の値に要素名「name」を記述します。name要素は子要素・属性を持たない、単純型の要素です。内容は文字列のみです。そこで、type属性を指定し、属性の値には「文字列」を表すデータ型、「xsd:string」を記述します。同じようにaddress要素も宣言します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
最後に、xsd:sequence、xsd:complexType、xsd:element、xsd:schema各要素の終了タグを記述して、XML Schemaの完成です。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
より複雑なXMLのスキーマ定義
今度はaddress要素にさらに子要素を追加してみましょう。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
このXMLの構造は以下のようになります。
要素名 | 特性 |
---|---|
customer | ルート要素。属性を持たない name、addressの2つの子要素を持つ name、addressの順に出現する |
address | 属性を持たない prefecture、city、streetの3つの子要素を持つ prefecture、city、streetの順に出現する |
name prefecture city street |
子要素、属性を持たない 内容には文字列のみ含まれる |
要素の数が増えても心配はいりません。1つ1つの要素を順番に宣言していけばよいのです。リスト3のXML文書のスキーマをXML Schemaで表すと、以下のようになります。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
先ほどのリスト2のXML Schemaと比較すると、address要素の宣言の部分が異なります。8〜18行目でaddress要素を宣言しています。address要素は子要素を持つ複雑型の要素です。そこで、xsd:complexType要素を使用し、その内容で子要素(prefecture、city、street)について、宣言します。
ref属性で要素を参照
リスト4のXML Schemaでは、address要素の宣言をcustomer要素の宣言の中に記述していました。すると、customer要素を宣言するxsd:element要素がとても大きくなってしまいました。このままでは、「customer要素がどんなデータ型なのか」非常に分かりづらいです。そこで、customer要素の宣言部分にはcustomer要素のデータ型のみを記述し、address要素については別の場所で説明しましょう。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
8行目でaddress 要素を宣言していますが、name属性を使用せずにref属性を使用しています。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
ref属性を記述した場合、要素の構造については別の場所で宣言します。そして、ref属性の値に記されている要素を参照します。
これは、「customer要素の2番目の子要素はaddress要素です。address要素に関しては別の場所に記述しています」という意味になります。そして、customer要素の宣言の後に、address要素の宣言を行います。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
ref属性を使用すると、たくさんの要素がある場合でもすっきりとしたXML Schemaを書くことができます。
属性を宣言する
customer要素に属性を加えてみましょう。customer要素に、顧客IDを表すid属性を追加します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
要素/属性名 | 特性 |
---|---|
customer | ルート要素。id 属性を持つ name、addressの2つの子要素を持つ name、addressの順に出現する |
name address |
子要素、属性を持たない 内容には文字列のみ含まれる |
id | 属性値に任意の文字列を指定可能 |
属性を追加する場合は、xsd:attribute要素を使用します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
属性も、子要素と同じようにxsd:complexType要素の内容(開始タグと終了タグの間)で宣言します。属性は、子要素について記述した後(ここではxsd:sequence要素の後)で宣言します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
属性は、xsd:attribute要素を使用して宣言します。属性の名前は、要素と同じようにname属性の値に指定します。ここでは「id」という名前の属性を宣言するので、name属性の値には「id」と記述します。属性のデータ型(属性値としてどのような値が記述できるか)は、type属性を使用して指定します。id属性は任意の文字列を属性値に指定できるので、type属性の値には「任意の文字列」を表すデータ型「xsd:string」を指定しましょう。
属性が複数ある場合も、xsd:attribute要素を使用して属性宣言を繰り返していけば、属性をいくつでも指定できます。
今回は子要素や属性を持つ要素を宣言する方法を説明しました。次回は、子要素の出現回数や出現の順番など、より細かく設定する方法について解説します。(次回に続く)
Copyright © ITmedia, Inc. All Rights Reserved.