エンジニアのためのXMLスキーマ講座
第2回:XMLの標準スキーマ表現 DTDを「読む」
(株)日本ユニテック
竹内 理
目次<全5ページ>
DTDを読む-属性リスト宣言
1 <!ENTITY salut "Dear Friends">
2 <!ENTITY % personal-data "name,mail-address">
3 <!ELEMENT email (front,body) >
4 <!ELEMENT front (from,to+,cc*,title) >
5 <!ELEMENT from (%personal-data;) >
6 <!ELEMENT to (%personal-data;) >
7 <!ELEMENT cc (%personal-data;) >
8 <!ELEMENT name (#PCDATA) >
9 <!ELEMENT mail-address (#PCDATA) >
10 <!ELEMENT title (#PCDATA) >
11 <!ELEMENT body (salution?,p*)>
12 <!ELEMENT salution (#PCDATA) >
13 <!ELEMENT p (#PCDATA) >
14 <!ATTLIST email seqnum NMTOKEN #REQUIRED
15
importance (LOW|HIGH) "LOW">
|
<リスト1.email.dtd>
リスト1の最後の2行(14、15行目)は属性リスト宣言です。この部分ではある要素がどのような属性を持つことが出来るのか、その属性の属性値の候補、属性のデフォルト値の3つを指定します。
次に属性リスト宣言の記述の仕方を示します。
<!ATTLIST 要素名 属性名 属性値の候補 "デフォルト値">
(デフォルト値の2重引用符はアポストロフィでもよい)
ひとつの要素に複数の属性を使えるように宣言するには次のようにまとめて記述できます。
<!ATTLIST 要素名 属性名1 属性値の候補 "デフォルト値"
属性名2 属性値の候補 "デフォルト値"
属性名3 属性値の候補 "デフォルト値">
「属性値の候補」の部分は大きく分けて2つのパターンをとります。ひとつは文字通りその属性値の候補を列挙するパターン、もうひとつはデータ型によって属性値の候補を示すパターンです。それぞれのパターンについて見ていきましょう。
<属性値の候補の定義1-列挙型>
具体的な属性の値を列挙し、その中から属性値を選択させるための定義方法です。属性値の候補を列挙する場合、次のような形をとります。
<!ATTLIST 要素名 属性名 (属性値の候補1|属性値の候補2|…) "デフォルト値">
このように、括弧の中で"|"で区切って属性値の候補を列挙します。リスト1の15行目はこの形で属性を宣言しています。
<!ATTLIST email importance (LOW|HIGH) "LOW">
この例だと、importance属性は"LOW"、"HIGH"の2つの値をとり得ます。なにも指定しない場合はデフォルトで"LOW"となります。
列挙する属性値はNMTOKEN型である必要があります(データ型については後述します)。
<属性値の候補の定義2-データ型による定義>
ある属性が持ちうる値のデータ型を指定するための定義方法です。ではそれぞれのデータ型と使用方法を見ていきましょう。
CDATA型
CDATA型の値は文字データで構成される属性値です。例えば次のような属性リスト宣言があるとします。
<!ATTLIST email exp CDATA #IMPLIED>
この場合、文書インスタンスでこの属性を使用するときは次のようになります。
<email exp="これはCDATA型の属性です">
このようにCDATA型の属性には2重引用符で囲まれた文字列を属性値として設定します。ちなみに整形式XML文書の場合は、特定の値を示す属性宣言がなされない場合、属性値は全てCDATA型であるとみなされます。
ID、IDREF、IDREFS属性
ID型の属性値は、その属性を持つ要素をXMLインスタンス中で一意に識別するために使われます。IDREF型の属性値は、その属性を持つ要素がID型の属性を持つ別の要素を参照する場合に使用します。
ID形の属性値はその文書インスタンス中で必ず一意である必要があります。同じID型の属性値が複数ある場合は正しく処理されません。また、ID型のデフォルト値は#IMPLIEDか#REQUIREDとなります(デフォルト値についての説明は後述します)。さらに、ひとつの要素が複数のID型の属性値を持つことは出来ません。
また、IDREF型やIDREFS型の属性値はその文書インスタンス中に存在するID型の属性値を指定する必要があります。
ID型やIDREF型の属性値は先頭の文字がアルファベット、カタカナ、ひらがななどの基本文字か漢字などの表意文字である必要があります(このような形の属性値などの文字列を「名前」の形であるといいます)。先頭の文字に数字を使うことが出来ないので注意してください。
では例で考えてみましょう。DTDの中に次のような記述があるとします。
<!ELEMENT person (#PCDATA) >
<!ATTLIST person pid ID #REQUIRED>
<!ELEMENT personref EMPTY>
<!ATTLIST personref refpid IDREF #REQUIRED>
この場合、文書インスタンス中では次のような使い方をすることができます。
<person pid="p1">佐藤 太郎</person>
<person pid="p2">鈴木 花子</person>
・・…・・…
<p>1人目の人<personref refpid="p1"/></p>
<p>2人目の人<personref refpid="p2"/></p>
この例ではpersonref要素を使用して、person要素を参照しています。personref要素のrefpid属性の属性値がperson要素のpid要素と対応していることに注目してください。
文書インスタンス中の複数の要素を参照する要素が必要な場合はIDREFS形の属性値を使用します。IDREFS型の属性値は参照する複数のID型の属性値をブランクで区切って指定することが出来ます。次に挙げるのはIDREFS型の属性値を持つrefpids属性を使用しているところです。
<p>1,2,3人目の人<personref refpids="p1 p2 p3"/></p>
NMTOKEN、NMTOKENS型
NMTOKEN、NMTOKENS型の属性値では「名前」の2番目以降に使用できる文字を、属性値の最初の文字に用いることが出来ます。ですから例えば"1"(NMTOKEN型)、"10s 21s 45s"(NMTOKENS型:NMTOKEN型の複数の属性値をブランクで区切る)というような属性値を持つことが出来ます。
ENTITY、ENTITIES型
エンティティ宣言のところで説明したように、DTDで宣言した内部エンティティは文書インスタンス中で&ent;の形で参照できます。しかし、XMLデータではない外部エンティティ(パース対象外エンティティ)は文書インスタンス中でどのように参照すればよいのでしょうか。
それは、要素にENTITY型(ENTITIES型)の属性値を持つ属性を設定することによって実現できます。
では例で考えてみましょう。次に挙げるのはエンティティ宣言を含むDTDの一部です。
<!ENTITY logo SYSTEM "http://…/logo.gif" NDATA gif>
…………
<!ELEMENT fig (#PCDATA)>
<!ATTLIST fig ref ENTITY #IMPLIED>
このDTDでは"logo"という外部エンティティが宣言されています。この外部エンティティは記法"gif"で書かれたパース対象外エンティティです。また、要素"fig"は図への参照を表す要素でref属性を持ちます。ref属性はENTITY型の属性値を持ちます。
このDTDの文書インスタンスは例えば次のようになるでしょう。
<p> <fig ref="logo">図</fig>を参照してください。</p>
ref属性の値がエンティティ名"logo"であることに注目してください。このようにして文書インスタンス中で"logo"というエンティティを参照することが出来るようになりました。
NMTOKENSやIDREFSと同じく、ENTITIES型の属性値は複数のエンティティを参照することが出来ます。ENTITIES型の属性値は複数のエンティティ名をブランクで区切って記述します。
NOTATION型
文書インスタンスのある要素が特定の記法を持つ、というような場合があります。例えば、ある日付を表す要素"date"があるとします。この要素が"yyyy-mm-dd"という形で日付を表すことをアプリケーションに知らせたい場合があるかもしれません。これは"date"要素の属性の属性値をNOTAION型にして記法宣言で宣言した記法名を属性値に指定することで実現できます(記法宣言については後述します)。
NOTATION型の属性値を持つ属性の宣言は他の場合と少し異なります。以下のように宣言します。
<!ATTLIST 要素名 属性名 NOTATION 記法名候補 デフォルト値>
"NOTATION"の後に記法名候補を記述する必要があることに注意してください。ここに記法名の候補を記述します。
では、先ほどのdate要素を含むDTDがどうなるのか、次の例を見てみましょう。
<!NOTATION UTF PUBLIC "ISO/IEC 8601//NOTATION Universal Time Format//EN">
<!ELEMENT date (#PCDATA) >
<!ATTLIST date type NOTATION (UTF) #REQUIRED>
1行目は記法宣言です。UTFという記法は"yyyy-mm-dd"の形の日付の記述の仕方を表します。2行目はdate要素の要素型宣言です。そして3行目はNOTATION型の属性値をもつ属性typeを宣言する属性リスト宣言です。type属性はUTFという記法名の候補を持っています。複数の記法名の候補がある場合は、それらの記法名を"|"で区切って記述する事が出来ます。
では、ここでここまで考えてきた属性値がとりうるデータ型をまとめておきましょう。
データ型 | 説明 |
CDATA | 文字データ。 |
ID | その文書インスタンスにおいて一意の識別子。 |
IDREF,IDREFS | 識別子と識別子参照値。 |
NMTOKEN、NMTOKENS | 「名前」の形の文字列の2番目以降の文字を最初の文字に出来る。 |
ENTITY、ENTITIES | エンティティ参照値 |
NOTATION | 記法参照値 |
<表5.属性値の型>
ここでもう一度属性リスト宣言の記述の仕方を見てみましょう。
<!ATTLIST 要素名 属性名 属性値の候補 "デフォルト値">
ここまで「属性値の候補」の定義について詳しく見てきましたが、次に「デフォルト値」の定義についても考えてみましょう。
デフォルト値の定義にはいくつかのパターンがあります。ではこれからそれぞれのパターンを順に見ていくことにいたしましょう。
二重引用符(あるいはアポストロフィ)で囲んだ属性値
これは文字通りのデフォルト値です。文書インスタンス中でその属性が明示的に指定されなかった場合、ここで書かれた属性値が適用されます。
リスト1の15行目はこのパターンを使用していました。
<!ATTLIST email importance (LOW|HIGH) "LOW">
この例はemail要素においてimportance属性が明示的に指定されなかった場合にはimportance属性の値は"LOW"であるとみなす、ということを表しています。
#REQUIREDキーワード
デフォルト値の定義が#REQUIREDである場合、その属性は「必須」であることをさします。
リスト1の14行目ではこのパターンを使用しています。
<!ATTLIST email seqnum NMTOKEN #REQUIRED>
文書インスタンスでemail要素を使用するときはseqnum属性は省略できません。必ず明示的に指定します。
#IMPLIEDキーワード
デフォルト値の定義が#IMPLIEDである場合、文書インスタンス中でその属性が明示的に設定されないとアプリケーションに属性値が渡されないとみなされます。この場合アプリケーションは独自のデフォルトの値を適用することになります。
次の例は属性リスト宣言で#IMPLIEDを使用しています。
<!ATTLIST person pid NMTOKEN #IMPLIED>
この場合、次のように文書インスタンスを記述できます。
<person pid="p1">……</person>
<person pid="p2">……</person>
<person>……</person>
3番目のperson要素には属性が指定されていないことに注目してください。
#FIXEDキーワード
#FIXEDキーワードを使用すると、その属性はひとつの決まった属性値しか指定できなくなります。
<!ATTLIST person name CDATA #FIXED "斎藤 次郎">
上の例の場合、name属性には”斎藤次郎”という値しか持つことが出来ません。次のような文書インスタンスはエラーになってしまいます。
<person name="佐藤 太郎">……</person>
ここで、属性リスト宣言のデフォルト値がとりうるパターンを以下にまとめておきます。
パターン | 説明 |
二重引用符で囲んだ属性値 | 文書インスタンス中でその属性が明示的に指定されなかった場合、ここに書いた属性値が適用される。 |
#REQUIRED | その属性は必須である。かならず明示的に指定する。 |
#IMPLIED | その属性が指定されない場合はアプリケーションに属性値は渡されない。 |
#FIXED | その属性は指定した値しか持てない。 |
<表6.属性リスト宣言のデフォルト値のパターン>
関連サービス
XMLスキーマの策定、作成業務
|