Class G


DTDの読み方

DTDは初めて見ると複雑で嫌になるかもしれませんが、読むのはそれほど難しくありません。

Contents

  1. DTDについて
  2. マーク宣言
  3. まとめ

DTDについて

DTDについては、HTML Structure - SGMLについてをご覧下さい。

以下は、HTML4.01のDTDです。

Frameset DTDは、ほぼTransitional DTDと同一です。以下の点が違います。

これを知っておけば十分ですが、Frameset DTDの読み方が知りたい方は、Frameset DTDの読み方をご覧下さい。

マーク宣言

ELEMENT宣言

要素宣言です。使用する要素名、タグの省略、内容型などを宣言します。以下のように宣言します。

<!ELEMENT 要素名 タグの省略 (内容型)>

では実際に、要素宣言を見てみましょう。ここでは、DL要素を例として使用します。

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

まず、DLで、要素名をDLとして宣言します。

次の「- -」ですが、これは前者が開始タグ、後者が終了タグを表します。「-」が指定されているときは、タグの省略は許可されません。省略が許可されるときは「O(大文字のオー)」が指定されます。

内容型の(DT|DD)+ですが、これは外側から見ていきます。まず括弧に「+」がついているので、「括弧内のものを一つ以上」という意味になります。そして中のDT|DD」は「DT要素、またはDD要素」という意味になります。

その後ろの「-- definition list --」は、コメントです。よくコメントを表すときに「<!-- コメント -->」としますが、SGMLでは、マーク宣言内に「--」が現れると、次に現れる「--」までをコメントとする決まりになっています。このコメント部分には、この要素の意味などが書かれていることが多いです。

これを全て読むと、「DL要素は、タグの省略は許可されず、内容にDT要素、またはDD要素を一つ以上含む。」ということになります。

内容型の宣言について

内容型の宣言では、いくつかの記号が使われます。まずは、それを理解する必要があります。

記号意味
?直前の要素が、0回または1回出現する。
+直前の要素が、1回以上出現する。
*直前の要素が、0回以上出現する。(なくてもよいということ)
+()直後の要素が出現してもよい。
-()直後の要素が出現してはならない。
,列挙される要素が、列挙された順序通りに出現する。
|列挙されたようそのうち、どれかが出現する。
&列挙された要素が出現するが、順序は問わない。
EMPTY内容を持ってはならない。(空要素)
#PCDATAテキストデータ。(#PCDATA)

PCDATAに#がついていますが、これについては#PCDATAをご覧下さい。

次に、これら記号を使った例文を見てみましょう。

内容型意味
xxが必ず1回だけ出現する。
x?xが0回、または1回出現する。
x+xが1回以上出現する。
x*xが0回以上出現する。(なくてもよい)
+(x)xが出現してもよい。
-(x)xが出現してはならない。
x , yxとyがこの順序で出現する。
x | yxまたはyが必ず出現する。
x & yxとyが必ず出現するが、順序は問わない。

ATTLIST宣言

属性リスト宣言です。要素が持つことのできる属性を列挙します。以下のように宣言します。

<!ATTLIST 要素名
  属性名 属性値 属性値の初期値
  >

実際には、改行はなくてもいいのですが、見にくいので普通は改行して列挙します。

属性値は、特定の文字列や実体定義、データ形式のいずれかを指定します。

まず、以下のFORM要素の例をご覧下さい。

<!ATTLIST FORM
  %attrs;                              -- %coreattrs, %i18n, %events --
  action      %URI;          #REQUIRED -- server-side form handler --
  method      (GET|POST)     GET       -- HTTP method used to submit the form--
  enctype     %ContentType;  "application/x-www-form-urlencoded"
  accept      %ContentTypes; #IMPLIED  -- list of MIME types for file upload --
  name        CDATA          #IMPLIED  -- name of form for scripting --
  onsubmit    %Script;       #IMPLIED  -- the form was submitted --
  onreset     %Script;       #IMPLIED  -- the form was reset --
  accept-charset %Charsets;  #IMPLIED  -- list of supported charsets --
  >

属性値の初期値に指定されているもので、例えばmethod属性は、指定しない場合はGETと見なされることを示します。enctype属性も同様に、指定しない場合は"application/x-www-form-urlencoded"と見なされることを示します。

先頭に#がついている物は#PCDATAと同様に、予約名であることを示します。以下にその意味を示します。

#IMPLIED

初期値がないことを示します。

これが指定されている属性は、属性自体が省略できますが、省略した場合の挙動については、各ウェブブラウザに任されます。

これ以外の初期値が指定されているものは、属性自体が省略できるわけではなく、省略しても何らかの初期値が与えられることになります。

#REQUIRED

その属性が省略不可の必須属性であることを示します。

これが指定されている属性以外は、一応全て省略可能です。

論理型属性

属性値に、ただ一つ属性名と全く同じ文字列を取り得る属性のことを、特に論理型属性と呼びます。

例えば、OPTION要素の、selected属性がこれにあたります。

selected    (selected)     #IMPLIED

見ての通り、属性名がselectedで、属性値にはselectedただ一つのみが取り得ます。

ENTITY宣言

実体宣言です。DTD内部でのみ使用される実体のことを、特にパラメータ実体と呼びます。任意の要素や属性の別名を定義するものです。以下のように宣言します。

<!ENTITY 実体名 "実体">

DTD内部でのみ使用するパラメータ実体の場合は、実体名の前に%を付加し、参照は%実体名;として参照します。

では、実際に宣言を見てみましょう。

<!ENTITY % heading "H1|H2|H3|H4|H5|H6">

実体名が「heading」で、実体がH1-H6要素です。こうすることによって、要素宣言が簡潔になります。

<!ELEMENT (%heading;) - - (%inline;)* -- heading -->

このようにすることで、一度にH1からH6までを、要素宣言しました。%inline;についても、どこかで定義されているわけです。

一般実体

ちなみに、パラメータ実体と違い、DTD外で使用する実体のことを一般実体と呼びます。一般実体では、宣言時に%は付加されず、参照時は&実体名;とすることで参照します。

これはいわゆる文字参照です。

まとめ

「よくわかんねーよ」、と言う感じかもしれませんが、要はとりあえず「<!ELEMENT 知りたい要素名」でDTD内を検索すれば知りたいものが出てきます。もしかしたら出てこないかもしれませんから、その場合は要素名そのもので検索してみましょう。どこかのENTITY宣言で実体定義されているかもしれません(先のH1-H6要素のように)。

DTDで見ることは、基本的にELEMENT宣言の内容型とATTLIST宣言です。「この要素は中になにを含むことができるのだろう」というときや「どんな属性があってその属性はどんな値をもてるのだろう」という時など、その都度見ていけばいいでしょう。一度に覚える必要はありません。