Document Type Definition

Document Type Definition（文書型定義、DTD）とは、マークアップ言語のSGMLおよびXMLにおいて、文書構造（文書型）を定義するためのスキーマ言語の一つである。
DTDでは、SGMLやXMLの文書内に記述することができる要素やその発生順序、発生回数、要素がもつ属性、属性の型などを記述することができる。
他のスキーマ言語と同様に、DTDにおいても、文書構造を厳密に定義することによって、SGMLやXMLの技術を利用する際の、処理の正確性や安全性を高めることができる。SGMLやXMLの文書処理を支援するライブラリの多くは、SGMLやXMLの文書がDTDによる文書構造に従っているかどうかを検証する機能を備えている。
もともとはSGMLのスキーマ言語として開発され、SGMLから派生したXMLにおいても、スキーマ言語として採用されている。例えば、SGMLの応用技術であるHTMLや、XMLの応用技術である XHTMLでは、DTDによって文書構造が定義されている。
現在では、XML技術を利用する場合には、スキーマ言語としてDTDを採用するケースは少なくなる傾向にある。XMLが勧告された後、DTDに対してはいくつかの欠点（XMLの文法とは異なる文法を採用していることや、XML名前空間に対応していないことなど）が問題として指摘されてきたためである。そのため、XML技術は広く普及したものの、DTDの欠点が XML技術を柔軟に活用する際の障害の一つとなっていた。
この問題を解決するために、新たなスキーマ言語としてRELAX NGやW3C XML Schemaなどが開発され、それらを採用する事例が増えている。
DTDの構造.
DTDは、要素型宣言、属性リスト宣言、エンティティ宣言（または、実体参照宣言）、記法宣言により構成される。
要素型宣言.
対象のSGML/XML文書において使用する要素を宣言し、その要素の名前、関連する要素との親子関係および出現順序を定義する。
 <!ELEMENT "要素名" "構成要素">
このとき、要素名は、対象の要素の名前であり、構成要素は、以下の種類に分けられる。
EMPTY.
対象要素に子要素が存在しない場合（例えば、後述する属性のみの場合など）に指定する。
<!ELEMENT foo1 EMPTY>
ANY.
対象要素配下に任意の要素、任意のデータが格納される場合に指定する。
<!ELEMENT foo2 ANY>
子要素.
対象要素配下の子要素の順番および出現回数を指定する。
<!ELEMENT foo1 (bar1,(bar2|bar3)*)>
属性リスト宣言.
対象のSGML/XML文書の要素が持つ属性の型やデフォルト値を定義する
 <!ATTLIST "要素名" "属性名" "属性値の候補、または型" "デフォルト値">
例えば、俳優の出身地域を属性として定義する場合、以下のような属性リストが考えられる。
 <!ATTLIST 俳優 出身地域 (北海道|東北|関東|甲信越|東海|北陸|近畿|四国|九州|沖縄) "関東">
 <俳優 出身地域="東海">俳優A</俳優>
エンティティ宣言、記法宣言.
エンティティ宣言は、対象のSGML/XML文書内に記述できるエンティティ参照について定義する。SGML/XML文書内でエンティティ参照を記述すると、DTDのエンティティ宣言にしたがって、文字列を置換したり、外部ファイルの内容を埋め込むことができる。
<!ENTITY greeting "こんにちは">
<!ENTITY external-file SYSTEM "external.xml">
記法宣言は、対象のSGML/XML文書内から参照する外部ファイルの種類 (例えばJPEGなど) を指定する。
DTDの例.
簡単なDTDの例を示す。
<!ELEMENT firstName (#PCDATA)>
<!ELEMENT secondName (#PCDATA)>
<!ELEMENT info ANY>
<!ELEMENT data (firstName,secondName,info?)>
<!ELEMENT myDocument (data)*>
<!ATTLIST data age CDATA #IMPLIED>
このDTDでは以下の内容が記述されている。
このDTDに従って作成したXML文書の例
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE myDocument SYSTEM "example.dtd">
 <myDocument>
 <data age="29">
 <firstName>Fred</firstName>
 <secondName>Bloggs</secondName>
 </data>
 <data>
 <firstName>Tony</firstName>
 <secondName>Blair</secondName>
 <info>PM of UK</info>
 </data>
 </myDocument>