S-JIS[2008-11-01/2009-10-19]

DTD(Document Type Definition)

DTDとは、Document Type Definition(文書型定義)のこと。
SGMLでも使われるらしいが、一番使われるのはXMLにおいてだろう。
xmlファイル内でどういうタグが使われるかを定義するのがDTD(やXMLスキーマ)。
XMLにおいては、今後はDTDよりもXMLスキーマが使われていくらしいが。

XMLでは、DTD(またはXMLスキーマ)を使って、xmlファイルが決められたタグだけを使っているかどうかを検証することが出来る。(妥当性検証)


DOCTYPE

検証にDTDを使う場合は、各xmlファイルの先頭で、どのDTDを使うかをDOCTYPEで指定する。

<?xml version="1.0" encoding="Shift_JIS" ?>
<!DOCTYPE root>
<root>
	〜
</root>

DOCTYPEの直後には、そのxmlファイル内で使用するルートタグ(要素名)(この例ではroot)を指定する。
(XMLにおいては、ルートタグは1つしか持ってはいけない)

DOCTYPEのルートタグ指定の後には、DTDの参照方法を書く。
直接DTDを書く方法や、ファイル名を指定する方法がある。


xmlファイル内に直接DTDを記述することが出来る。

<?xml version="1.0" encoding="Shift_JIS" ?>
<!DOCTYPE root [
	〜ここにDTDを書く〜
]>
<root>
	〜
</root>

sample1.xml:

<?xml version="1.0" encoding="Shift_JIS" ?>
<!DOCTYPE root [
<!ELEMENT root (data)* >
<!ELEMENT data (#PCDATA) >
]>
<root>
	<data>データ1</data>
	<data>データ2</data>
</root>

DTDだけを記述したdtdファイルを作ることも出来る。

C:\dtd\sample.dtd

<!ELEMENT root (data)* >
<!ELEMENT data (#PCDATA) >

sample2.xml:

<?xml version="1.0" encoding="Shift_JIS" ?>
<!DOCTYPE root SYSTEM "file:C:/dtd/sample.dtd">
<root>
	<data>データ1</data>
	<data>データ2</data>
</root>

DOCTYPEのルートタグ指定の後に「SYSTEM」と書き、その後にdtdファイルの場所を書く。

ファイル名の指定は、システム識別子と呼ばれるらしい。
妥当性検証の際にそのファイルが読み込まれる。 システム識別子を「http://」から始めれば、インターネット経由でdtdファイルをダウンロードしてくることになる。


また、公開識別子というものもある。

sample3.xml:

<?xml version="1.0" encoding="Shift_JIS" ?>
<!DOCTYPE root
	PUBLIC "-//hishidama//DTD xml-dtd sample//EN"
	"file:C:/dtd/sample.dtd">
<root>
	<data>データ1</data>
	<data>データ2</data>
</root>

DOCTYPEのルートタグ指定の後に「PUBLIC」と書き、その直後に公開識別子を書く。
公開識別子の後ろにはシステム識別子(dtdファイルの場所)を記述する。

公開識別子の構成にもいろいろルールがあるようだ(が、自分でこれ作る人はあんまりいないだろうねー)
→M.Kanzakiさんの文書型宣言の意味

しかし実のところ、公開識別子は単なる情報(説明・タイトル)であり、そんなに必須なものではないらしい。
でもxmlファイルを扱うソフト(検証ツールやブラウザー)によっては公開識別子を見る事があるようなので、XMLの定義(DTD)がきちんとしている場合は、そのDTD用の公開識別子を一言一句変更せずに記述しておくべき。
Javaで公開識別子を見てシステム識別子を変更する例


公開識別子やシステム識別子と内部DTDを併せて書くことも出来る。

sample4.xml:

<?xml version="1.0" encoding="Shift_JIS" ?>
<!DOCTYPE root SYSTEM "file:C:/dtd/sample.dtd" [
<!ENTITY name "hishidama">
]>
<root>
	<data>My name is &name;</data>
</root>

DTDの構文

DTDでは、xmlファイル内で使用するタグ(要素)とそのタグで使用できる属性や、実体参照を定義することが出来る。

DTD 概要 文法 例の説明
ELEMENT 要素 <!ELEMENT 要素名 (内容モデル)> <!ELEMENT root (data)* > root要素の中には、data要素を0個以上入れることが出来る。
ATTLIST 属性リスト <!ATTLIST 要素名 属性名 データ型 "デフォルト値">    
ENTITY 実体参照 <!ENTITY 実体名 "内容"> <!ENTITY name "hishidama"> xmlファイル内で&name;を使うと「hishidama」に置き換わる。
  コメント <!-- コメント -->    

SGMLでは、ELEMENTの構文は「<!ELEMENT 要素名 - - 内容モデル>」という形らしい。「- -」は、開始タグ・終了タグが省略不可であることを示している(終了タグが省略可能な場合、「- O」となるらしい)。
しかしXMLでは、タグを省略することは出来ない。したがって省略可否を表す部分は無い。

ELEMENTの「内容モデル」では、自分の要素の中にどんな要素がどんな順序で何回現れるかを定義する。

形式 説明 備考
a aが1回  
a? aが0回または1回  
a* aが0回以上  
a+ aが1回以上  
a,b aの次にb 順序が決まっている
a|b a又はb いずれか1つ
() グループ化 (a|b)+」といった感じ
#PCDATA 文字列 他の要素が入るのではなく、文字列が入る
EMPTY 他の要素を持たない
ANY DTD内に現れた要素なら何でも可

参考


妥当なXML文書

XMLに関して、「well-formed」とか「妥当なXML文書」という言葉がある。[2009-10-19]

xmlファイルは、開始タグと終了タグで囲まれているとかネストしてないとかの条件(最低限のルール)があり、それを満たしていると「well-formed XML document(整形式XML文書)」と呼ばれるらしい。
少なくともこれら最低限のルールを満たしていないと、xmlファイルとして扱えない。

さらに、「valid XML document(妥当なXML文書)」とは、DTD(やXMLスキーマ)を使った検証(定義されたタグだけ使用されているとか 指定されたデータしか使っていないとか)を通るものを指すらしい。

「valid」を「妥当」と訳すのは、直訳的な訳語としては正しいのかもしれないが、ニュアンスが伝わっていないような気がする。
(「このxmlファイルは妥当です」と言われたら、最低限を満たしているだけという感じがする…)
「完全なXML文書」「完璧なXML文書」「定義に沿ったXML文書」とかの方が近いんじゃないかなぁ。


誰が妥当性検証を行うのか?

xmlファイルは、DTD(やXMLスキーマ)によって、そのXMLの妥当性検証を行うことが出来る。

実際に検証を行うのは、そのxmlファイルを読み込むアプリケーション。しかし検証することが必須という訳でもないので、検証するかどうかすらそのアプリ次第。

例えばHTMLもW3Cによって作られているDTDで検証することが出来るはず。だが、ブラウザーがhtmlファイルの検証を行っているかと言えば、たぶん行っていないだろう。
例えばxmlファイルをIE6で開いた場合は、dtdファイルを読み込みはするが検証はしないっぽい(苦笑)
例えばWebLogic10というAPサーバーは、読み込んだweb.xmlの妥当性検証を行っている。
Javaでxmlファイルを検証する方法

基本的に、検証を行う際にはシステム識別子で示されたファイルを参照する。場合によってはインターネットにアクセスしてdtdファイルをダウンロードする。
しかし検証ツールによっては、xmlファイル内で指定された公開識別子が「ツール内部で保持している公開識別子」と等しければ、dtdファイルをダウンロードせずに自分自身が内部で保持しているDTDを使って検証することも出来るようだ。そうすれば、dtdファイルを外部から取得する必要が無い。
Javaでxmlファイル検証の前にシステム識別子を変更する方法


技術メモへ戻る
メールの送信先:ひしだま