文書型宣言の読み方

この文書の最新版は「鳩丸よもやま話 : 文書型宣言の読み方」に移転しています。以下の文章は古くなっているかも知れません。

HTMLの骨組みと 文書型宣言

まず、HTMLの骨組みについておさらいしてみましょう。HTML 4.0で書かれたシンプルな HTML文書は以下のようになります。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"
 "http://www.w3.org/TR/REC-html40/strict.dtd">
<HTML>
<HEAD>
<TITLE>ここにタイトルを書きます。</TITLE>
</HEAD>
<BODY>
<P>ここに本文を書きます。</P>
</BODY>
</HTML>

文書の先頭、<HTML> の前に記述されているものが、文書型宣言あるいは DOCTYPE宣言と呼ばれるものです。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">

という記述を、順に検証してみましょう。

<!

まず、この <!DOCTYPE ……> は「タグ」ではありません。これは SGMLの「マーク宣言(markup declaration)」です。SGMLでは、他にも <!ENTTITY……> や <!SGML……> などのマーク宣言が使われますし、お馴染みの <!--コメント--> もマーク宣言の一種です。

<! はマーク宣言開始区切り子(MDO) で、その名の通りマーク宣言の開始を意味します。あくまで、"<!" で一つの記号です。開始タグ開始区切り子 "<" に "!" がくっついているのではありません。当然、< と ! の間に空白を入れたりしてはいけません。

DOCTYPE

続く DOCTYPE は宣言の種類を表す予約名で、これが 文書型宣言であることを示しています。<! の後に空白を入れることは許されていません。ぴったりくっつけて半角で DOCTYPE と記してください。

HTML

次に HTMLと書かれていますが、これは「文書型名」です。要するに当該文書のルートエレメント名を示しています。これによって文書全体が HTML 要素に属することになり、それゆえ <HTML> と </HTML> で括られることになるのです。

ここでたとえば <!DOCTYPE BODY …… などとすると、ルートエレメントは BODY になります。HEAD 要素のない、HTML文書ならぬ BODY文書? が宣言されることになるのです(もちろんそんなことをしてはいけません)。

……ということですので、この宣言は <HTML> などというタグがでてくる前に書かなくてはなりません。

文書型宣言の前には空白文字と注釈宣言、処理命令を書くことが出来ます。けれども、余分なものを書かずに文書型宣言で始めた方がいいでしょう。もっとも、XML では XML宣言という処理命令が先頭に来るのが普通です。

PUBLIC

HTML の次に PUBLIC と書かれていますが、これは外部識別子です。外部に公開されている文書を参照し、その場所にそっくりそのまま貼り付けることになります。

<!DOCTYPE HTML [<!ELEMENT……>……]>とやってその場で DTD を記述する方法もあるのですが、各文書に巨大な DTD を記述するのは効率が悪いので、外部ファイルを参照するという方法が使われます。

"-//W3C//DTD HTML 4.0//EN"

PUBLICのうしろにある二重引用符の中身、これは参照する文書を特定する「公開識別子」です。HTML では SGML宣言で「FORMAL YES」と宣言されているので、特に「公的公開識別子」という物が用いられます。

公的公開識別子は、所有者識別子 ("-//W3C") 、区切り子 ("//") 、文識別子 ("DTD HTML 4.0//EN") 、という形になっています。

所有者識別子

所有者識別子は、その外部文書の所有者を表します。この場合、所有者は W3C です。 -// で始まるのは「未登録所有者識別子」で、この所有者が正式登録されていないことを示します。登録があると +// です。

文識別子

続く文識別子は、順に「公開文種別」("DTD")、「公開文記述」("HTML 4.0")、区切り子 ("//") 、公開文言語 ("EN"=英語) となっています。

この EN は参照先の DTD の言語を示しています。参照元の HTML文書の言語ではありません。これを勝手に JA に書き換えてしまう人がいるようですが、そんなことをしてはいけません。

ちなみに、公開文種別や公開文言語の指定は大文字で行わなくてはなりません。

"http://www.w3.org/TR/REC-html40/strict.dtd"

最後に記述されているのは、システム識別子です。ここでは単に DTD の所在を示す URI となっています。

これは PUBLIC の公開識別子を補足するものなので、公開識別子だけで文書が識別できるならば省略しても構いません。逆に、システム識別子だけを使うことも出来ます。その場合は "PUBLIC" の代わりに "SYSTEM" を使って、

<!DOCTYPE HTML SYSTEM "http://www.w3.org/TR/REC-html40/strict.dtd">

のようにしますが、HTML の文書型宣言にはこの形は使われません。

>

最後に > 。マーク宣言終了区切り子(MDC)で、宣言を閉じます。

SYSTEM 識別子は必要か?

末尾にはシステム識別子がくっついています。けれども、SGML的には PUBLIC と宣言して公開識別子を使っているのですから、システム識別子は省略可能です。現に HTML 3.2 以前ではシステム識別子はずっと省略されていました。

では、なぜこんなものがついているのでしょうか。仕様書 19.1 を見てみましょう。

If the document type declaration of your document includes a URI and your SGML parser supports this type of system identifier, it will get the DTD directly.

要するに、システム識別子を解釈するパーサーが勝手に DTD をダウンロードしてきて文書を検証できるように、という親切心なのです。けれども皮肉なことに、この親切心で逆に誤動作してしまうパーサーも存在します

仕様書にはシステム識別子を省略して良いとは書かれていませんけれども、SGML的には問題ありませんし、なにより仕様書のソースが「省略できる」と雄弁に物語っているようにも思えます。

文書型宣言を忘れると?

基本的に、SGML文書には文書型宣言が必須です。これを省略することは出来ません。HTML も SGML応用系ですから、文書型宣言が絶対に必要です。

もっとも、XML文書は文書型宣言を要しないことがあります。

では、文書型宣言を書き忘れてしまうとどういうことになるのでしょうか。

RFC1866 には、以下のような記述があります。

NOTE - If the body of a `text/html' message entity does not begin with a document type declaration, an HTML user agent should infer the above document type declaration.

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0 Level 2//EN">

つまり、HTML2.0の時点では、「文書型宣言を省略すると HTML2.0 とみなす」というルールが確立していたのです(なお、HTML2.0 は "-//IETF//DTD HTML//EN" で、"-//IETF//DTD HTML 2.0 Level 2//EN" とは違うのではないか、と思う人もいるかもしれませんが、両者は同じ DTD を参照しています)。ですから、HTML2.0 に対応したブラウザは、文書型宣言のない文書を HTML2.0 とみなすでしょう。しかし、現在では少し事情が違います。

HTML4.0 仕様書 附記Bには、以下のような解説があります。

The HTML 2.0 specification ([RFC1866]) observes that many HTML 2.0 user agents assume that a document that does not begin with a document type declaration refers to the HTML 2.0 specification. As experience shows that this is a poor assumption, the current specification does not recommend this behavior.

HTML4.0では、「HTML2.0 とみなすことは推奨しない」と言っています。これは HTML2.0 の記述を上書きしていると考えて良いでしょう。では、文書型宣言のない文書がどう扱われるのか……と言われると、分かりません。「HTML2.0 とみなす必要はない」とは言っていますが、それ以上のことは何も言っていないのです。穿った見方をすれば、この解釈は各ユーザーエージェントに一任されているということなのかも知れません。


マニアックな文法論議

HTML鳩丸倶楽部

水無月ばけら, MINAZUKI Bakera
E-mail: bakera@star.email.ne.jp