DTD:Document Type Definition

1.DTDの概要

DTD:XML文書で使用する要素名やその階層構造(要素親子関係)、属性名やその内容を定義することにより、実際のXML文書でどのようにタグ付けを行うかを規定する。

DTDの記述方法

  • 内部サブセット:XML文書の内部に記述する方法。
  • 外部サブセット:DTDの部分だけを取り出し、別ファイルとして保管しておく方法。

DTDの全体構造

  • 要素型宣言(element type declaration):キーワード:ELEMENT…XML文書を構成する要素の名前、内容、登場順番について定義する。
  • 属性リスト宣言(attribute list declaration):キーワード:ATTLIST…XML文書内の要素が持つ属性の名前、型、デフォルト値を定義する。
  • 実体宣言(entity declaration):キーワード:ENTITY…XML文書本体やDTDから参照される実体の名前や実体の内容を定義する。
  • 記法宣言(notation declaration):キーワード:NOTATION…外部リソース(画像データ等)のデータ形式を定義する。

2.要素型宣言

要素型宣言の書式:<!ELEMENT 要素名 内容モデル>
  • 要素名:大文字小文字は区別される。同じ要素名を持つ要素宣言を複数指定することはできない。要素名に指定された要素は、内容モデルに記述された要素の「親要素」になる。
  • 内容モデル(content model):対象となる要素に関連付けられたルールのこと。
  • 内容モデルとして指定可能な主なパターン
    • (#PCDATA):内容として文字データしか持たない要素
    • 要素内容(子要素名一覧):子要素を一つ以上持つ要素
    • 混合内容(#PCDATA|子要素名一覧):文字データと子要素の両方を持つ要素。
内容モデルで指定可能な記号
記号 説明
, 各要素を区切り、順番を指定する
| |で区切られた要素のいずれかが出現
? 要素が0回または1回出現可能
* 要素が0回以上出現可能
+ 要素が1回以上出現可能
() ひとまとまりの要素を表す。入れ子にすることができる

◇ 内容モデルパターン:#PCDATA(Parsed Character Dataの省略)

要素の内容として文字データしか持たせない定義をする場合に指定するバターンである。

書式:<!ELEMENT 要素名(#PCDATA)>
<!ELEMENT root(#PCDATA)>

上記のDTDによって空要素で記述した場合は妥当な文書である。
<root/>

◇ 内容モデルパターン:要素内容

複数の子要素を必ず指定の順番に出現させる場合の指定方法

<!ELEMENT 要素名(子要素名a,子要素名b)> 子要素名と子要素名の間を「,」で区切る。

<!ELEMENT root(a,b)>
<!ELEMENT a (#PCDATA)>
<!ELEMENT b (#PCDATA)>
複数の子要素のうち、いずれか1つだけを出現させる場合の指定方法

<!ELEMENT 要素名(子要素名a|子要素名b)> 子要素名と子要素名の間を「|」で区切る。

<!ELEMENT root(a|b)>
<!ELEMENT a (#PCDATA)>
<!ELEMENT b (#PCDATA)>
  • 要素aと要素bが共に出現した場合は妥当なXML文書ではない。
  • 要素aと要素bのいずれも出現していなければ、妥当なXML文書ではない。
1回だけ出現させる場合の指定方法

<!ELEMENT 要素名(子要素名a)>

<!ELEMENT root(a)>
<!ELEMENT a (#PCDATA)>
  • 要素aは2回以上出現すると、妥当なXML文書にならない。
  • 要素aは1回も出現していなければ、妥当なXML文書にならない。
0回または1回出現させる場合の指定方法

<!ELEMENT 要素名(子要素名a?)>

<!ELEMENT root(a?)>
<!ELEMENT a (#PCDATA)>

<!ELEMENT 要素名(子要素名a,子要素b)?>
<!ELEMENT root(a,b)?>
<!ELEMENT a (#PCDATA)>
<!ELEMENT b (#PCDATA)>

※上記のDTDは「a要素とb要素がこの順番で1回ずつ出現する」というパターンが0回か1回出現するという指定になる。
下記、要素aのみ出現している場合、上記のDTDに反するため、妥当なXMLではない。
<!DOCTYPE root SYSTEM "sample.dtd">
<root>
 <a>100</a>
</root>
1回以上何度でも出現させる場合の指定方法

<!ELEMENT 要素名(子要素名a+)>

<!ELEMENT root(a+)>
<!ELEMENT a (#PCDATA)>

※空要素の場合、妥当なXML文書と認められない。
<!ELEMENT 要素名(子要素名a,b)+>
<!ELEMENT root(a,b)+>
<!ELEMENT a (#PCDATA)>
<!ELEMENT b (#PCDATA)>
0回以上何度でも出現させる場合の指定方法

<!ELEMENT 要素名(子要素名a*)>
<!ELEMENT 要素名(子要素名a,b)*>

入れ子構造の定義

例:

<!ELEMENT root(a,(x|y)*)>
<!ELEMENT a (#PCDATA)>
<!ELEMENT x (#PCDATA)>
<!ELEMENT y (#PCDATA)>

◇ 内容モデルパターン:混合内容(mixed content)

混合内容の要素を定義すると、文字データや子要素の出現順序や出現回数は何度でも(0回以上)、どのような順序で出現しても構わない。
<!ELEMENT 要素名(#PCDATA|子要素a|子要素b….)*>

  • #PCDATAは必ず先頭に記述しなければならない。
  • #PCDATAと子要素の区切り記号は「|」となる。
  • 修飾記号に使えるのは「*」のみ。修飾記号の省略もできない。

◇ 内容モデルパターン:EMPTY

その要素の内容を空要素として定義する場合に指定するパターンとなる。
<!ELEMENT 要素名 EMPTY>

属性リスト宣言

属性リスト宣言の書式:

<!ATTLIST 要素名 属性名 (候補値a|候補値b) "デフォルト値">
<!ATTLIST 要素名 属性名 属性のデータ型 "デフォルト値">

  • 要素名:属性を持たせる要素の名前を指定する。
  • 属性名:属性の名前を指定する。属性名は大文字小文字を区別する。
  • 候補値:属性値の候補が複数ある場合は、その値(文字列)を「|」で区切って列挙する。候補値文字列はシングルクォーテーションやダブルクォーテーションで囲まない。
  • 属性のデータ型:XML文書で記述する属性値のデータ型を決められたキーワードで指定する。DTDでは、属性値の長さや桁数は指定できない。
  • デフォルト値:実際のXML文書で属性が記述されなかった場合に使用する値を指定する。

属性に指定できるデータ型

DTDで指定できる属性のデータ型
データ型 説明
CDATA 文字データを表すデータ型
ID 一意識別子
IDREF 一意識別子への参照
IDREFS 複数の一意識別子への参照
NMTOKEN 名前として使用できる文字(2文字目以降)を記述するためのデータ型
NMTOKENS 複数のNMTOKENの値。空白で区切る
ENTITY 外部実体の名前
ENTITIES 複数のENTITYの値、空白で区切る
列挙 ユーザーが指定した属性値のリスト
CDATA型

最も一般的な文字データを表す。DTDの属性データ型には、整数値、数値、日付といった一般的なデータ型に対応するデータ型は無いので、そのため、これらのデータを使用する場合、DTD内ではCDATA型(文字データ)として定義する。
CDATAを用いた属性リスト宣言の例(sample.dtd)

<!ATTLIST root attr CDATA #IMPLIED>
<!ELEMENT root (#PCDATA)>
ID型、IDREF型、IDREFS型
  • ID型は重複しない値をその要素に付加するために使用するデータ型である。
  • ID型と指定した属性の値はそのXML文書で記述されている全てのID型で一意(ユニーク)になるようにする。
  • 1つの要素に対して、ID型を指定した属性は複数指定できない。
  • ID型に指定できる値は、要素名や属性名と同じ規則(命名規則)に従う。
  • IDREF型とIDREFS型は、ID型の属性に設定された値を参照するためのデータ型である。

ID型とIDREF型を使用した属性リスト宣言の例(sample.dtd)

<!ATTLIST product  code ID #REQUIRED>
<!ATTLIST customer  pro_ref IDREF #IMPLIED>
<!ELEMENT root (product|customer)*>
<!ELEMENT product (#PCDATA)>
<!ELEMENT customer (#PCDATA)>
NMTOKEN型、NMTOKENS型

NMTOKEN型とNMTOKENS型は名前として使用できる文字を記述するために指定するデータ型である。

ENTITY型、ENTITIES型

ENTITY型とENTITIES型は、実体の参照を属性値として指定することにより、実体をXML文書の一部として取り込む時に指定する。この指定をすることにより外部ファイルに作成したデータ(XML文書でなくてもよい)をXML文書で使用できる。

1つの要素に複数の属性を設定する方法

個々の属性ごとに別々の属性リスト宣言を行う指定方法
<!ATTLIST 要素名 属性名X 候補値a "デフォルト値">
<!ATTLIST 要素名 属性名Y 候補値b "デフォルト値">
<!ATTLIST 要素名 属性名Z 候補値c "デフォルト値">
1つの属性リスト宣言内に複数の属性を宣言する指定方法
<!ATTLIST 要素名 属性名X 候補値a "デフォルト値"
              属性名Y 候補値b "デフォルト値"
              属性名Z 候補値c "デフォルト値">

デフォルト値の指定方法

指定できる値 説明
デフォルト属性値データ XML文書で属性が省略されたときに設定される値
#REQUIRED XML文書で属性の省略を許可しない場合に指定する
#IMPLIED XML文書で属性の省略を許可する場合に指定する
#FIXED "固定値" XML文書で指定できる属性値を限定する場合に指定する

重複した属性リスト宣言

同じ要素に対して、同じ属性名の属性リスト宣言が別々の場所で指定されていた場合は、最初に定義された宣言が有効となる。

属性値の正規化:XMLサーバーは解析の際、属性値の正規化手順は以下となる。

  1. 属性値に文字参照があれば置き換える。
  2. 内部実体(置換文字列)があれば置き換える。
  3. 行末の復帰文字、または復帰文字+改行文字を改行文字に変換する。その結果、改行文字が連続して記述されている場合、まとめて1つの半角空白に置き換える。
  4. 属性値に「タブ」がある場合には、半角空白に置き換える。
  5. 正規化した結果、DTDで指定した型のうちCDATA型以外は連続する半角空白を1つの半角空白に置き換える。属性値の先頭と末尾に半角空白があればそれを削除する。

3.実体宣言

実体分類

実体が使用される場所による分類:一般実体とパラメータ
  • パラメータ実体:DTDの中で使用される実体を示す。
  • 一般実体:DTD以外で使用される実体を示す。
実体の存在場所による分類:外部実体と内部実体
  • 外部実体:XML文書内で参照する実体は、その内容がファイルとして作成されていることを示す。
  • 内部実体:XML文書内で参照する実体は、DBDの実体宣言内に文字列として定義されていることを示す。
実体の内容がXML文書として解析対象となるかどうかによる分類:解析対象実体と解析対象外実体
  • 解析対象実体:実体の内容がXML文書として解析対象であることを示す。解析対象実体は、テキストデータとして作成される。
  • 解析対象外実体:実体の内容がXML文書として解析できないことを示す。XML文書に直接記述できないため、必ず外部実体としてファイルに作成される。また、解析対象外実体は、DTD内で参照できないので注意が必要である。

定義済み一般実体参照

置き換える文字(実体) 実体名 実体参照
< lt &lt;
> gt &gt;
& amp &amp;
" quot &quot;
' apos &apos;

内部一般実体の定義方法と参照方法

内部一般実体の宣言方法:
<!ENTITY 実体名 "文字列">
内部一般実体の参照方法:
&実体名;

パラメータ実体の定義方法と参照方法

パラメータ実体の宣言方法:
<!ENTITY % 実体名 "文字列">
パラメータ実体の参照方法:
%実体名;

<!ENTITY % para "(#PCDATA|a|b)*" >
<!ELEMENT  x %para;>
<!ELEMENT  y %para;>
<!ELEMENT root (x|y)>
<!ELEMENT  a (#PCDATA)>
<!ELEMENT  b (#PCDATA)>

外部実体の定義方法と参照方法

外部実体とは、ファイルとして作成してあるXML文書やテキスト、画像などを実体として参照し、XML文書の一部として利用できるようにしたものである。

外部解析対象実体

外部解析対象実体の宣言方法:
<!ENTITY 実体名 SYSTEM "外部実体の場所を示すURI">
外部解析対象実体の参照方法:
&実体名;
外部ファイルテキスト宣言:
<?xml version="1.0" encoding="文字エンコーディング"?>
※エンコーディングがUTF-8、UTF-16の場合に省略できる。

標準化団体などの提供する実体を利用する方法

標準化団体などの提供する実体を利用する場合は、公開識別子を使用する方法がある。公開識別子とはISOなどの標準化団体や業界などで広く利用することを目的として開発され、DTDや実体宣言集などを特定するための表現方法である。
公開識別子を用いた実体の宣言:
 <!ENTITY 実体名 PUBLIC "公開識別子">
公開識別子を用いた実体の参照:
 &実体名;
公開識別子の記述方法:
 "公開された名前" "公開されたURI"
公開された名称の記述方法:
 承認状況//文書の所有者名など//文書の種類//ISO639言語識別子

  • 承認状況:標準化団体が承認しているか否かを示す。承認している場合は記号(+)を記述し、承認していない場合は記号(-)を記述する。
  • 文書の所有者名jなど:その文書の作成者や所有者または組織名等を記述する。
  • 文書の種類:文書に何が記述されているかを示す。
  • ISO639言語識別子:その内容を記述している言語を示す。
<!ENTITY smaple "-//W3C//DTD specification V2.1 for XML 1.0//EN" "http://www.w3.org/XML/1998/06/xmlspec-v21a.dtd">
外部解析対象外実体

解析対象外実体の宣言:
 <!ENTITY 実行名 SYSTEM "外部実体の場所を示すURI" NDATA 記法名>
解析対象外実体の参照:解析対象外実体は、ENTITY型またENTITIES型の属性値としてのみ参照可能
 <!ATTLIST 要素名 属性名 ENTITY "デフォルト値">
 <要素名 属性名="実体名"/>

4.記法宣言

記法宣言では、解析対象外実体などがどのようなデータ形式になっているかを定義する。基本宣言で定義した記法の名前を記法名と呼ぶ。

記法の宣言

<!NOTATION 記法名 SYSTEM "記法を特定するURI">
※同じ記法名を複数の記法宣言で重複して指定することはできない。

記法の参照

解析対象外実体での参照:
 <!ENTITY 実体名 SYSTEM "実体の場所を示すURI" NDATA 記法名>
属性リスト宣言での参照:
 <!ENTITY 要素名 属性名 NOTATION 記法名 デフォルト値>
空要素として宣言された要素にはNOTATION型の属性値を宣言できない。

5.内部サブセットと外部サブセットの併用上の留意点

  • XMLでは要素型宣言や記法宣言の重複指定は許さない。
  • 属性リスト宣言や実体宣言の重複指定は許す。
  • 内部DTDと外部DTDを併用した場合、内部DTDが先に処理される。

使用例:
外部サブセット(sample.dtd)

<?xml version="1.0" encoding="Shift_JIS" ?>
<!ELEMENT a (#PCDATA)>
<!ATTLIST a color CDATA #REQUIRED>

妥当なXML文書
<?xml version="1.0" encoding="Shift_JIS" ?>
<!DOCTYPE root SYSTEM "sample.dtd" [
<!ELEMENT root (a)>
<!ATTLIST a color (red|blue) "blue">
]>
<root>
  <a color="red">aaa</a>
</root>

上記の例については内部DTDと外部DTDの両方でa要素のcolor属性の属性リスト宣言を指定しているが、内部DTDが優先されて解釈される。
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License