Section 14 : DTD を読む(2)

 内容モデルの記述は,文書構造の関係を定義するのにひじょうに重要な役割をもっており,独特の記号の組み合わせで表現される。

内容モデルの定義

 Section 13 で見たように,DTD における要素の定義の最後は内容モデルの記述である。ここには,書くことのできる要素名やデータタイプが記号と組み合わされて表現される。

 順序や回数を決める記号は次のとおり。

( ... )
かっこでくくると“ひとまとまり”である。
A | B
セパレータで区切られると“A または B のいずれか”を表す。
A , B
カンマで区切られると“A と B がこの順で”を表す。
A & B
アンパサンドで区切られると“A と B の両方,ただし順不同”を表す。
A?
疑問符は“あってもなくてもよい,ただし 2 つ以上あってはいけない(zero or one time)”を表す。
A*
アスタリスクは“1 つもなくても,何回出てきてもよい(zero or more times)”を表す。
A+
プラスは“少なくとも 1 回(one or more times)”を表す。
DTD での順序・反復の記号は,図式を用いて表すこともできる。
図 14.1 [D]

|」,「,」,「&」は,3 つ以上の要素やデータタイプを結ぶときがある。たとえば,(A | B | C) は“A,B,C のいずれかひとつ”,(A , B , C) は“A,B,C がこの順で”を表す。

 これらの組み合わせで,かなり複雑な状況も現れうる。かっこの位置も重要で,たとえば,

(A+ | B+)
(A | B)+

(A+ | B+) と (A | B)+ は,“どちらかが出現するか,どちらも出現してよいか”という点が異なる。
図 14.2 [D]

の 2 つがまったく異なる意味であることはおわかりいただけるであろう。前者は,A か B の片方しか出てこられないが(“A が 1 回以上”または“B が 1 回以上”),後者は,A も B も両方出てくることができる(“A または B”が 1 回以上)。

<!ELEMENT OL - - (LI)+                 -- ordered list -->

 ここからわかるように,<OL> の内容は <LI> で,少なくとも 1 回は出てこなくてはいけない。しかも,#PCDATA を含んでいないので,<OL> の直下にテキストを記述するのは間違いであることがわかる。

<!ELEMENT DL - - (DT|DD)+              -- definition list -->

 <DL> の内容が <DT><DD> であることはおなじみだが,これを見ると“‘<DT><DD>’が 1 回以上”すなわち,内容として,<DT><DD> かを選ぶ,ということを 1 回以上繰り返すということになる。

 内容モデルの指定はそれほど複雑なものは出てこない。次に,よく出てくる記号の組み合わせを示しておくので,これは覚えてしまうのがよい。

(A | B | C | ...)*
(A | B | C | ...)+

DTD によく出現する (A | B | C)* と (A | B | C)+ の形の構文。基本的に“候補からどれでも好きなだけ選ぶ”ことである。
図 14.3 [D]

 両方とも“かっこ内の要素は順不同で何度でも出てきて構わない”になるが,後者はその要素の中に少なくとも 1 つの要素・データタイプが含まれていなくてはならない。

 ただし,<TABLE> だけは難しいので,ここで説明を加えておこう。

<!ELEMENT TABLE - -
     (CAPTION?, (COL*|COLGROUP*), THEAD?, TFOOT?, TBODY+)>
<TABLE> の内容の構文を図式化したもの。
図 14.4 [D]

 <TABLE> の内容はまず,“順序がある”ことに注目してほしい。そのなかで,最初にくるのは <CAPTION> だが,これはなくてもよい(2 つ以上はいけない)。次は“‘<COL> が任意の回数’か‘<COLGROUP> が任意の回数’”である。<DL> の場合と見比べればわかるように,もし,<COL><TABLE>直接の下位要素となったら <COLGROUP> は同時には <TABLE>直接の下位要素たりえない。逆も同様である。このとき,“<COL><COLGROUP> もない”という状況もあり得ることに注意したい。ついで,<THEAD><TFOOT> が順に現れるが,? がついているのでなくてもよい。最後は <TBODY> で,+ を伴っているので 1 度以上この要素が現れる必要がある。

 文章にするとかなりややこしくなってしまうが,記号の意味をよく理解して,頭の体操だと思って内容モデルを考えていただきたい。

 また,“下位要素から除外”“下位要素に含める”という表し方がなされる場合がある。

<!ELEMENT A - - (%inline;)* -(A)       -- anchor -->

 “(%inline;)*”というのは,%inline; を展開して出てくる要素のなかのどれでも,何回でも出てきてよいということだが(“または,または,……”が何回でも),うしろに但し書き“-(A)”がある。これは“下位要素として(直接でも間接でも<A> は含んではならない”ということである。つまり“アンカは入れ子にしてはならない”ということである。たとえば,

<A HREF="...">See <EM>this <A HREF="...">site!</A></EM></A>

というのは誤りである。

 逆に,「+」に従えられた“但し書き”は“下位要素として(直接でも間接でも)含んでよい”を表す。たとえば,

<!ELEMENT BODY O O (%block;|SCRIPT)+ +(INS|DEL) -- document body -->

では,<BODY> の下位要素として,たとえ直接でなくても <INS> または <DEL> が出現してもよいことを表している。

 内容モデルの指定についても,DTD で間に合わない部分については,仕様書で補足されることがある。注意されたい。