DTDの初歩
DTDとは、XMLのスキーマ言語の1つの名称である。 スキーマ言語とは、文章の構造を定義する言語である。 XMLに関して言えば、要素の入れ子関係やタグ付けのルールなどがそれに当たる。 DTDはSGMLの時代から使われているもので、 XMLには不似合いだとしてXML用のスキーマ言語「XML Schema」なるものが 考え出されているが、仕様が複雑で標準化は進んでいない。 一方で、「RELAX」というスキーマ言語も存在する。 RELAXはシンプルな構造で、XML Schema並みの記述性を持っている スキーマ言語として普及が始まっている。しかし現在のXML文書の スキーマ言語として最も定着しているのはDTDであり、 その必要性は今後も続くと考えられている。 DTDの基本的な構成は、「要素型宣言」、「属性リスト宣言」、 「エンティティ宣言」、「記法宣言」に分割して考えられる。 ここでは要素、属性、そしてエンティティについて簡単に説明しておく。
要素
要素は以下のような形で宣言される。

<!ELEMENT 要素名 内容モデル>

要素名とは要素の名前である。内容モデルには、 その要素に含まれる別の要素名を複数記述することが出来る。 それらの別の要素を、この要素を親要素と呼ぶことに対して、 子要素と呼ぶ。例えば人間を表す要素を考えると以下のようになる。

<!ELEMENT 人間 (苗字, 名前)>

この例は、人間要素には苗字と名前という別の要素を 内容として定義しなければならない事を表す。 この内容モデルに順序は、XMLを記述する際にも保持しなければならない。 つまり、現れた順序のまま記述する。

また同時に、内容モデルには内容の個数を記述することもできる。 上記の例では苗字要素と名前要素を1つずつ (それより多くても少なくてもいけない)記述しなければならないが、 たとえば人間要素の子要素として「趣味」要素を宣言したい場合、 それは任意の数を取れるべきである(人によってはいくつも趣味があるかも知れない)。 そこで以下のように記述する。

<!ELEMENT 人間 (苗字, 名前, 趣味*)>

上のように書けば、趣味のない人間がいてもいいし、 あるいは100個の趣味を持つ人間がいてもいい。 これは上記の「*」が、「0回以上出現する」という意味を持つためである。 このような記述の方法には、他に以下のようなものがある。

<!ELEMENT SAMPLE (TEST)> 1回のみ出現する
<!ELEMENT SAMPLE (TEST)*> 0回以上出現する
<!ELEMENT SAMPLE (TEST)+> 1回以上出現する
<!ELEMENT SAMPLE (TEST)?> 0回か1回出現する

また、内容モデルには子要素以外のものを記述することも可能である。 その要素の内容が文字列だった場合は「#PCDATA」と記述する。 このように指定された要素は、子要素を持たずその内容を記述する。
属性
属性の宣言は以下のような形で行う。

<!ATTLIST 要素名 属性名 属性値の候補 "デフォルト値">

要素名はこの属性を記述する対象となる要素の名前である。属性名はこの属性の名前である。 また、属性値の候補には属性値のデータ型を記述する。データ型には次ページのような種類がある。

CDATA 文字データ
ID 識別子
IDREF 識別子参照値
IDREFS 複数のIDREFの属性値
NMTOKEN 「名前トークン」というタイプの文字列
NMTOKENS 複数の「名前トークン」
ENTITY エンティティ参照値
ENTITIES 複数のエンティティ参照値

デフォルト値には、その名の通りデフォルトの値を書くことが出来るが、 その他にも「#REQUIRED」と「#IMPLIED」という文字列を書くことが出来る。 #REQUIREDはその属性を必ず書かなければならないことを表す。 つまり、デフォルト値は必要ない。また、#IMPLIEDは省略可能であることを表す。 省略した場合は、属性値としてアプリケーションに何も渡さない。

これらを踏まえて、先ほどの人間要素に属性を付加してみる。 例えば、人間要素に性別と年齢を属性として加えると、属性宣言は以下のようになる。

<!ATTLIST 性別 人間 CDATA #REQUIRED>

<!ATTLIST 年齢 人間 CDATA #IMPLIED>

上の例だと、性別は必ず書かなくてはならないが、 年齢は省略可能であることが分かる。 また、どちらも任意の文字データを指定できる。 例えば上記のDTDに従ったXMLを記述すると、 以下のようになる(人間要素の定義部分のみ)。

<人間 性別="男" 年齢="20">
・・・・・・
</人間>

<人間 性別="女">
・・・・・・
</人間>

上記のように、人間要素には性別属性の記述は必須であるが、年齢は省略できる。
エンティティ
エンティティは以下のように宣言する。

<!ENTITY エンティティ名 "置換される文字列">

エンティティ名にはエンティティの名前を記述する。 エンティティとはマクロのようなものである。 XML中に「&エンティティ名;」と記述すると、 それは上記の"置換される文字列"に置換される。 これは例えば、XML中に何度も出てくる記述をまとめるのに便利である。 それを変更する際には、エンティティのみを変更すればよい。