文書型宣言で内部サブセットと外部サブセットを宣言する

初稿: 2005-08-24

意外と知られていない文書型宣言

XHTMLを知っている人は文書の最初に「DOCTYPE」という記述を見たことがあるでしょう。しかし、これが何を意味するかを知っている人は意外と少ないと思います。今回はこの文書型宣言(Document type declaration)と呼ばれる記述について触れてみます。

文書型宣言でサブセットを宣言

まず文書型宣言がどんなものか見てみましょう。

<?xml version="1.0"?>
<!DOCTYPE bookshelf SYSTEM "bookshelf.dtd">

<bookshelf>
  <book code="ISBN0-0000-0000-1">
    <title>はじめてのXML</title>
    <author>桃 太郎</author>
  </book>
  <book code="ISBN0-0000-0000-2">
    <title>XML入門</title>
    <author>金 太郎</author>
  </book>
</bookshelf>

上記で強調された箇所が文書型宣言です。文書型宣言とはそのXML文書内での利用するサブセットを宣言するものです。サブセットの定義はXMLの仕様の中で用意されたDTDという文法によって記述されますが、その定義が記述される個所によってサブセットを2つに分類することができます。XML文書自体の中に定義が記述されたものを内部サブセット(Internal Subset)、XML文書の外で定義が記述されたものを外部サブセット(External Subset)と呼びます。これらはどちらか片方しか利用できないというわけではなく、両方を同時に利用することができます。ただし内部サブセットと外部サブセットで定義が重複することも考えられます。この場合は内部サブセットが優先されます。一般的には、あるXML文書に限りサブセットを利用する場合には内部サブセットを、複数のXML文書でサブセットを利用する場合には外部サブセットを定義します。実際にXHTMLでは外部サブセットが定義されています。

文書型宣言の文法

文書型宣言は内部サブセットと外部サブセットの宣言で文法が違います。内部サブセットを宣言する場合、以下のように記述されます。

<!DOCTYPE サブセット名 [内部サブセット定義]>

「サブセット名」はサブセットのルート要素の要素型と一致しなければなりません。また「内部サブセット定義」には直接サブセットの定義がDTDにより記述されます。これに対して外部サブセットの宣言では、外部サブセットを参照するために外部識別子を使用します。外部識別子(External Identifier)とは外部サブセットを識別しその位置を参照するためのもので、システム識別子と公開識別子の 2 つの種類が存在します。このうちシステム識別子(System Identifier)とは外部サブセットの位置を示すもので、URIで表現されます。XMLパーサはこの位置情報から外部サブセットを入手します。もう一方の公開識別子(Public Identifier)とは特定の外部サブセットを表す識別子として、公に知られている文字列を使用するものです。代表的な例では XHTML を表す公開識別子として「-//W3C//DTD XHTML 1.1//EN」が知られています。公開識別子はXMLパーサによって既にこの文字列が知られていることを前提としています。ここで文書型宣言はシステム識別子による外部サブセットの宣言の場合、以下のように記述されます。

<!DOCTYPE サブセット名 SYSTEM "システム識別子">

このとき「システム識別子」はURIで表されます。次にシステム識別子による外部サブセットの宣言の場合、以下のように記述されます。

<!DOCTYPE サブセット名 PUBLIC "公開識別子" "システム識別子">

「システム識別子」は「公開識別子」の代替として働きます。XML パーサが公開識別子を知らなかった場合、「システム識別子」から外部サブセットを参照します。

より具体的に

下図では文書型宣言で内部サブセットの利用を指定しています。

内部サブセット

このように文書型宣言の中にDTDによって内部サブセットの定義が記述されます。次に下図は外部サブセットの利用を指定しています。

外部サブセット

システム識別子によって指定された先の「bookshelf.dtd」の中でDTDによって外部サブセットの定義が記述されます。


目次へ戻る