DTDを使ったXML構造の定義

広告
eyecatch

XML は任意のタグを使って文書を作成できる言語ですが、あらかじめ XML 文書をどのようなタグを使って記述するのかルールを決めておき、そのルールに従って文書が作成されているかチェックすることができます。ここではルールの定義を行う言語のひとつである DTD(Document Type Definition) に関する解説と、 DTD を使った XML 文書の構造を定義する方法について解説します。

※ XML 文書の基本的な作成方法については「XML入門」を参照されてください。

(2020 年 03 月 15 日公開 / 2020 年 03 月 18 日更新)

DTDとは

まず最初に DTD とはどのようなもので、どんな場合に使用するのかについて簡単に解説します。

例えば支店毎の在庫データを XML 文書で作成してもらい、それを本部で集計する場合を考えてみます。各支店で独自のタグを使って文書を作成してしまうと、各支店から XML 文書を受けとり処理する側はとても大変です。

A支店の在庫に関する文書:

<?xml version="1.0" encoding="UTF-8" ?>
<在庫>
    <商品>
        <名前>自転車</名前>
        <在庫数>20</在庫数>
    </商品>
</在庫>

B支店の在庫に関する文書:

<?xml version="1.0" encoding="UTF-8" ?>
<在庫データ>
    <商品>
        <商品情報>
            <商品名>本棚</商品名>
            <取得年月日>20xx年3月</取得年月日>
        </商品情報>
        <個数>12</個数>
    </商品>
</在庫データ>

そこでどの要素をどのように使用するのか XML の構造を定義します。各支店は同じルールに従って XML 文書を作成します。下記は同じルールに従って作成した XML 文書です。

A支店の在庫に関する文書:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品)>
    <!ELEMENT 商品 (名前, 個数)>
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT 個数 (#PCDATA)>
]>

<在庫データ>
    <商品>
        <名前>自転車</名前>
        <個数>20</個数>
    </商品>
</在庫データ>

B支店の在庫に関する文書:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品)>
    <!ELEMENT 商品 (名前, 個数)>
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT 個数 (#PCDATA)>
]>

<在庫データ>
    <商品>
        <名前>本棚</名前>
        <個数>12</個数>
    </商品>
</在庫データ>

共通したルールに従って XML 文書が作成されていますので、どの要素の値がどんな値を表しているのかはっきりわかるようになりました。またプログラムなどで文書を処理する場合にも、使用されているタグが分かっていますので処理しやすくなります。

この XML 文書の構造を定義するのに使用するが DTD です。 DTD は XML 文書の構造を定義するための言語と考えて下さい。先ほどのサンプルの場合次の部分が DTD となります。

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品)>
    <!ELEMENT 商品 (名前, 個数)>
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT 個数 (#PCDATA)>
]>

DTD を使って定義した XML の構造は XML 文書の中に直接書いたり外部のファイルとして保存し読み込むことができます。

XML文書がDTDに準拠しているか検証する

DTD の記述方法を見ていく前に、作成した XML 文書が DTD に照らし合わせて問題ないかどうかをチェックする方法を確認しておきます。いくつかのところからツールが提供されていますが、今回は次のサービスを利用しました(このサイトに問題があるかどうかの保証はできません。利用される場合は自己責任でお願いいたします)。

http://xmlvalidator.new-studio.org/

XML文書がDTDに準拠しているか検証する(1)

DTD をチェックしたあとで「ファイルを選択」をクリックしてください。ファイル選択ダイアログが表示されますので、検証したい XML 文書のファイルを選択してください。

XML文書がDTDに準拠しているか検証する(2)

今回は次のような XML 文書を事前に作成し保存したものを選択しました。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品)>
    <!ELEMENT 商品 (名前, 個数)>
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT 個数 (#PCDATA)>
]>

<在庫データ>
    <商品>
        <名前>自転車</名前>
        <個数>20</個数>
    </商品>
</在庫データ>

ファイルの選択が終わりましたら「Check」をクリックしてください。

XML文書がDTDに準拠しているか検証する(3)

次のように「Validation successful!」と表示されれば妥当な XML 文書です。(妥当な XML 文書とは DTD によって取り決められたルールに適合している文書のことです。)

XML文書がDTDに準拠しているか検証する(4)

では先ほどの XML 文書を少し変更し、 DTD に従っていない文書にしてみます。(タグ名を「個数」から「商品数」に変更してあります)。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品)>
    <!ELEMENT 商品 (名前, 個数)>
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT 個数 (#PCDATA)>
]>

<在庫データ>
    <商品>
        <名前>自転車</名前>
        <商品数>20</商品数>
    </商品>
</在庫データ>

先ほどと同じようにチェックを行ってみると、今度は 2 つのエラーが表示されました。

XML文書がDTDに準拠しているか検証する(5)

このように検証ツールを使用することで、作成した XML 文書が DTD で定めたルールに従って作成されているかを確認することができます。

文書型宣言(DOCTYPE宣言)と要素型宣言

文書型宣言( DOCTYPE 宣言)は XML 文書と、 XML 文書の構造を定義した DTD とを結びつけるために使用します。

構造を内部に記述するか、それとも外部のファイルに記述して読み込むかによって少し形式は異なりますが、内部に記述する場合の文書型宣言は次のような形式になります。

<!DOCTYPE ルート要素名[
    ・・・
]>

「ルート要素名」には対象となる XML 文書のルート要素の要素名を記述します。(ルート要素というのは XML 文書の一番外側にある要素です。詳しくは「要素を記述する」を参照されてください)。

そして「・・・」の部分に XML 文書の構造である要素型宣言を記述していきます(他にも属性リスト宣言や実体宣言などを記述できます)。要素型宣言では XML 文書の中でどのような要素が含まれるのかを記述します。要素型宣言は次のような形式となります。

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

「要素名」に記述した要素の中に子要素を持つのか又はテキストを記述するのかなどを「内容モデル」のところで記述します。

次の XML 文書を見てください。文書型宣言は赤色の部分、要素型宣言は青色の部分です。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品)>
    <!ELEMENT 商品 (名前, 個数)>
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT 個数 (#PCDATA)>
]>

<在庫データ>
    <商品>
        <名前>自転車</名前>
        <個数>20</個数>
    </商品>
</在庫データ>

文書型宣言では対象となる XML 文書のルート要素が「在庫データ」ですので、「在庫データ」がルート要素名のところに記述されています。

要素型宣言についてはこの後で詳しく記述方法を解説しますが、「在庫データ」要素には「商品」要素が含まれ、「商品」要素には「名前」要素と「個数」要素がこの順番に含まれ、「名前」要素にはテキストが含まれ、「個数」要素にはテキストが含まれると定義されています。実際 XML 文書もそのような構造になっています。

要素型宣言の記述方法

要素型宣言で XML 文書の中に含まれる要素の名前や出現する回数などを定義していきます。記述するイメージとしては、ルート要素に含まれる要素から定義し、階層の上から下に向かって順番に定義していく感じです。

指定した要素が子要素として含まれる

要素の中に特定の子要素が一つ含まれる場合は次のように記述します。

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

例えば次のように DTD を記述した場合、 XML 文書では「在庫データ」要素には「商品」要素が一つ含まれる必要があります。

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品)>
>]>

さらに「商品」要素に別の子要素である「名前」要素が一つ含まれる場合には次のように DTD を記述します。

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品)>
    <!ELEMENT 商品 (名前)>
>]>

要素の中に複数の子要素がそれぞれ一つ含まれる場合は次のように記述します。

<!ELEMENT 親要素名 (子要素名1, 子要素名2, ...)>

例えば次のように DTD を記述した場合、 XML 文書では「在庫データ」要素には「名前」要素と「個数」要素がそれぞれ一つ含まれる必要があります。また記述する順番も最初に「名前」要素で次が「個数」要素である必要があります。

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (名前, 個数)>
>]>

-- --

簡単なサンプルを作成してみます。次のような XML 文書を作成しました。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品)>
    <!ELEMENT 商品 (名前, 個数)>
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT 個数 (#PCDATA)>
]>

<在庫データ>
    <商品>
        <名前>自転車</名前>
        <個数>20</個数>
    </商品>
</在庫データ>

DTD では「在庫データ」要素には「商品」要素が含まれ、「商品」要素には「名前」要素と「個数」要素が含まれ、「名前」要素と「個数」要素にはテキストデータが含まれることを定義しています。

作成した XML 文書を XML Validator でチェックしてみると妥当な XML 文書と表示されました。

指定した要素が子要素として含まれる(1)

-- --

次に「名前」要素と「個数」要素の記述する順番を変更してみます。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品)>
    <!ELEMENT 商品 (名前, 個数)>
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT 個数 (#PCDATA)>
]>

<在庫データ>
    <商品>
        <個数>20</個数>
        <名前>自転車</名前>
    </商品>
</在庫データ>

作成した XML 文書を XML Validator でチェックしてみるとエラーが表示されました。

指定した要素が子要素として含まれる(2)

複数記述した要素の中から一つが子要素として含まれる

要素の中に、複数の要素の中から一つだけが一つ含まれる場合は次のように記述します。

<!ELEMENT 親要素名 (子要素名1 | 子要素名2 | ...)>

例えば次のように DTD を記述した場合、 XML 文書では「ユーザー」要素には「名前」要素か「メールアドレス」要素のどちらかの要素が一つ含まれる必要があります。両方含むことはできません。

<!DOCTYPE 登録データ[
    <!ELEMENT ユーザー (名前 | メールアドレス)>
>]>

-- --

簡単なサンプルを作成してみます。次のような XML 文書を作成しました。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 登録データ[
    <!ELEMENT 登録データ (ユーザー+)>
    <!ELEMENT ユーザー (ユーザー名, パスワード)>
    <!ELEMENT ユーザー名 (名前 | メールアドレス)>
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT メールアドレス (#PCDATA)>
    <!ELEMENT パスワード (#PCDATA)>
]>

<登録データ>
    <ユーザー>
        <ユーザー名>
            <名前>山田太郎</名前>
        </ユーザー名>
        <パスワード>xxxxx</パスワード>
    </ユーザー>
    <ユーザー>
        <ユーザー名>
            <メールアドレス>suzuki@example.jp</メールアドレス>
        </ユーザー名>
        <パスワード>xxxxx</パスワード>
    </ユーザー>
</登録データ>

DTD では「登録データ」要素には「ユーザー」要素が 1 回以上含まれ、「ユーザー」要素には「ユーザー名」要素と「パスワード」要素が含まれ、「ユーザー名」には「名前」要素か「メールアドレス」要素のどちらか一つが含まれ、「名前」要素と「メールアドレス」要素と「パスワード」要素にはテキストデータが含まれることを定義しています。

※ 「<!ELEMENT 登録データ (ユーザー+)>」で「ユーザー名」の後に「+」が記述されています。これはこの要素が 1 回以上含まれる(複数個記述できる)ことを表していいます。詳しくはあとで解説します。

作成した XML 文書を XML Validator でチェックしてみると妥当な XML 文書と表示されました。

複数記述した要素の中から一つが子要素として含まれる(1)

-- --

次に本来は「名前」要素と「メールアドレス」要素のどちらか一つなのですが、両方を記述するように変更してみます。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 登録データ[
    <!ELEMENT 登録データ (ユーザー+)>
    <!ELEMENT ユーザー (ユーザー名, パスワード)>
    <!ELEMENT ユーザー名 (名前 | メールアドレス)>
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT メールアドレス (#PCDATA)>
    <!ELEMENT パスワード (#PCDATA)>
]>

<登録データ>
    <ユーザー>
        <ユーザー名>
            <名前>山田太郎</名前>
            <メールアドレス>yamada@example.jp</メールアドレス>
        </ユーザー名>
        <パスワード>xxxxx</パスワード>
    </ユーザー>
</登録データ>

作成した XML 文書を XML Validator でチェックしてみるとエラーが表示されました。

複数記述した要素の中から一つが子要素として含まれる(2)

要素にテキストデータが含まれる

要素にテキストデータが含まれる場合は次のように記述します。

<!ELEMENT 要素名 (#PCDATA)>

例えば次のように DTD を記述した場合、 XML 文書では「名前」要素と「年齢」要素にはテキストデータが含まれる必要があります。

<!DOCTYPE 登録データ[
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT 年齢 (#PCDATA)>
>]>

実際の使い方については今までのサンプルを参照されてください。

要素の出現回数を指定する

ここまで要素に子要素が含まれる場合の記述方法を見てきました。

<!ELEMENT 親要素名 (子要素名)>
<!ELEMENT 親要素名 (子要素名1, 子要素名2, ...)>

上記の場合、親要素には子要素が 1 つだけ含まれることを定義しており、 1 回以上子要素を記述するとエラーとなります。ただ XML 文書では同じ要素が複数記述される場合もあります。このような場合には要素の出現回数を次の文字を使って指定します。

+  1 回以上含まれる
?  0 回か 1 回含まれる
*  0 回以上含まれる

例えば同じ要素が 1 回以上含まれる場合には、子要素名の次に「+」を記述します。

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

また複数の子要素を持つ場合、それぞれに対して出現回数を指定することができます。

<!ELEMENT 親要素名 (子要素名1*, 子要素名2?, 子要素3)>

「?」や「*」を使用する場合は 0 回でも許可されるので要素を省略することができます。

-- --

簡単なサンプルを作成してみます。次のような XML 文書を作成しました。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 登録データ[
    <!ELEMENT 登録データ (ユーザー+)>
    <!ELEMENT ユーザー (名前, ニックネーム?, 趣味*)>
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT ニックネーム (#PCDATA)>
    <!ELEMENT 趣味 (#PCDATA)>
]>

<登録データ>
    <ユーザー>
        <名前>山田太郎</名前>
        <ニックネーム>タロウ</ニックネーム>
        <趣味>写真</趣味>
    </ユーザー>
    <ユーザー>
        <名前>鈴木次郎</名前>
        <趣味>映画</趣味>
        <趣味>旅行</趣味>
        <趣味>歴史</趣味>
    </ユーザー>
    <ユーザー>
        <名前>近藤花子</名前>
        <ニックネーム>ハナ</ニックネーム>
    </ユーザー>
</登録データ>

DTD では「登録データ」要素には「ユーザー」要素が 1 回以上含まれます。そして「ユーザー」要素には「名前」要素が 1 回、「ニックネーム」要素が 0 回か 1 回、「趣味」要素が 0 回以上含まれます。そして「名前」要素と「ニックネーム」要素と「趣味」要素にはテキストデータが含まれます。

先ほどの XML 文書には「ユーザー」要素が 3 回含まれており、それぞれの要素にはいずれも「名前」要素が 1 回含まれています。「ニックネーム」要素は含まれないか、または 1 回だけ含まれています。「趣味」要素は含まれなくてもいいですし何回含まれていても構いません。

作成した XML 文書を XML Validator でチェックしてみると妥当な XML 文書と表示されました。

要素の出現回数を指定する(1)

-- --

先ほどの XML 文書を少し変更し、「ニックネーム」要素が 2 回含まれるように変更してみます。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 登録データ[
    <!ELEMENT 登録データ (ユーザー+)>
    <!ELEMENT ユーザー (名前, ニックネーム?, 趣味*)>
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT ニックネーム (#PCDATA)>
    <!ELEMENT 趣味 (#PCDATA)>
]>

<登録データ>
    <ユーザー>
        <名前>山田太郎</名前>
        <ニックネーム>タロウ</ニックネーム>
        <ニックネーム>ヤマサン</ニックネーム>
        <趣味>写真</趣味>
    </ユーザー>
</登録データ>

作成した XML 文書を XML Validator でチェックしてみるとエラーが表示されました。

要素の出現回数を指定する(2)

要素とテキストデータが混在して含まれる

ここまで要素に子要素かテキストデータのどちらか一つを記述してきました。

<!ELEMENT 親要素名 (子要素名)>
<!ELEMENT 親要素名 (#PCDATA)>

もし要素とテキストデータの両方が混在したものを要素に含ませたい場合には次のように記述します。

<!ELEMENT 親要素名 (#PCDATA | 子要素名)*>

親要素にはテキストデータまたは子要素のいずれか一つが含まれますが、出現回数を表す「*」を付けることでテキストデータまたは子要素が何回でも親要素に含めることができるようになります。

-- --

簡単なサンプルを作成してみます。次のような XML 文書を作成しました。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 商品データ[
    <!ELEMENT 商品データ (商品+)>
    <!ELEMENT 商品 (名前, 概要)>
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT 概要 (#PCDATA | 強調)*>
    <!ELEMENT 強調 (#PCDATA)>
]>

<商品データ>
    <商品>
        <名前>消せる鉛筆</名前>
        <概要>書いた文字が<強調>簡単に</強調>消せます</概要>
    </商品>
    <商品>
        <名前>カラフル鉛筆</名前>
        <概要>自動的に<強調>色が変わる</強調>鉛筆です</概要>
    </商品>
</商品データ>

DTD では「商品データ」要素には「商品」要素が 1 回以上含まれます。そして「商品」要素には「名前」要素と「概要」要素が含まれ、「概要」要素にはテキストデータと「強調」要素のいずれか 0 回以上繰り返し含まれます。「名前」要素と「強調」要素にはテキストデータが含まれます。

実際に「概要」要素を見てみると、テキストデータと「強調」要素が混在した形で含まれています。

作成した XML 文書を XML Validator でチェックしてみると妥当な XML 文書と表示されました。

要素とテキストデータが混在して含まれる(1)

空要素を指定する

要素を空要素に限定して、要素の内容にテキストデータや子要素を記述できないようにするには次のように定義します。

<!ELEMENT 要素名 EMPTY>

この要素は必ず空要素である必要があります。

-- --

簡単なサンプルを作成してみます。次のような XML 文書を作成しました。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 商品データ[
    <!ELEMENT 商品データ (商品+)>
    <!ELEMENT 商品 (名前, 画像)>
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT 画像 EMPTY>
]>

<商品データ>
    <商品>
        <名前>消せる鉛筆</名前>
        <画像 />
    </商品>
    <商品>
        <名前>カラフル鉛筆</名前>
        <画像 />
    </商品>
</商品データ>

DTD では「商品データ」要素には「商品」要素が 1 回以上含まれます。そして「商品」要素には「名前」要素と「画像」要素が含まれます。「名前」要素にはテキストデータが含まれ、「画像」要素は空要素である必要があります。

作成した XML 文書を XML Validator でチェックしてみると妥当な XML 文書と表示されました。

空要素を指定する(1)

要素に任意の要素やテキストデータを含めることができるようにする

要素の内容として ANY を定義すると、テキストデータや DTD で定義されている他の要素を自由に記述することができます。

<!ELEMENT 要素名 ANY>

どのような場合にこの指定方法を使うべきなのかは現時点では分かりませんでした。

-- --

簡単なサンプルを作成してみます。次のような XML 文書を作成しました。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 商品データ[
    <!ELEMENT 商品データ (商品+)>
    <!ELEMENT 商品 (名前, その他)>
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT その他 ANY>
]>

<商品データ>
    <商品>
        <名前>消せる鉛筆</名前>
        <その他>来年春に発売予定です</その他>
    </商品>
    <商品>
        <名前>カラフル鉛筆</名前>
        <その他>
            参考商品
            <商品>
                <名前>カラフルペン</名前>
                <その他>発売中止</その他>
            </商品>
        </その他>
    </商品>
</商品データ>

DTD では「商品データ」要素には「商品」要素が 1 回以上含まれます。そして「商品」要素には「名前」要素と「その他」要素が含まれます。「名前」要素にはテキストデータが含まれます。「その他」要素は ANY が指定されており任意の内容を記述できます。

1 つ目の「商品」要素の中では「その他」要素にはテキストデータが記述されていますが、 2 つ目の「商品」要素の中では「その他」要素にはテキストデータの他に「商品」要素を子要素として記述しています。このように ANY を指定した要素では、 DTD で定義された他の要素を自由に記述することができます。

作成した XML 文書を XML Validator でチェックしてみると妥当な XML 文書と表示されました。

要素に任意の要素やテキストデータを含めることができるようにする(1)

属性リスト宣言の記述方法

要素型宣言は XML 文書の中に含まれる要素の名前や出現する回数などを定義したものでしたが、属性リスト宣言は要素に記述される属性について定義したものになります。( XML における属性について詳しくは「属性を記述する」を参照されてください)。

属性リスト宣言は次のような形式となります。

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

記述する場所は要素型宣言と同じく文書型宣言の中に記述します。次の XML 文書を見てください。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品+)>
    <!ELEMENT 商品 (名前, 個数)>
    <!ATTLIST 商品 商品番号 ID #REQUIRED>
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT 個数 (#PCDATA)>
]>

<在庫データ>
    <商品 商品番号="TN102">
        <名前>自転車</名前>
        <個数>20</個数>
    </商品>
    <商品 商品番号="EB315">
        <名前>花瓶</名前>
        <個数>12</個数>
    </商品>
</在庫データ>

赤色で記述された部分が属性リスト宣言と、それに対応して要素に記述された属性です。今回は「商品」要素に対する「商品番号」属性について定義しました。

また同じ要素に対して複数の属性について記述する場合は、別々に記述するかひとつにまとめて記述するかのいずれかの方法で記述します。

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

それでは属性リスト宣言の属性値の候補とデフォルト値の記述の仕方について見ていきます。

属性リスト宣言のデフォルト値を指定する

まず最初にデフォルト値の指定方法から確認します。デフォルト値として指定できるのは次の 4 種類です。

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

#REQUIRED
#IMPLIED
"属性値"
#FIXED "属性値"

それでは順に確認していきます。

#REQUIREDと#IMPLIED

デフォルト値として #REQUIRED を指定した場合は対象となる要素に必ず属性を記述しなければなりません。逆に #IMPLIED を指定した場合には対象となる要素に属性を記述してもしなくても構いません。(なお CDATA はあとで解説しますが任意の値を属性値に記述できる場合に指定する属性値の候補です)。

<!ATTLIST 商品 商品番号 CDATA #REQUIRED>
<!ATTLIST 商品 商品番号 CDATA #IMPLIED>

次の XML 文書を見てください。「商品」要素に対して「商品番号」属性を必ず記述するように指定しています。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品+)>
    <!ELEMENT 商品 (#PCDATA)>
    <!ATTLIST 商品 商品番号 CDATA #REQUIRED>
]>

<在庫データ>
    <商品 商品番号="TN102">鉛筆</商品>
    <商品>消しゴム</商品>
</在庫データ>

「商品」要素は「商品番号」属性が必ず記述されている必要があるのに 2 つ目の「商品」要素では属性が記述されていないため、作成した XML 文書を XML Validator でチェックしてみるとエラーとなります。

#REQUIREDと#IMPLIED(1)

今度は「商品」要素に対して「商品番号」属性を記述してもしなくてもいいように指定しています。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品+)>
    <!ELEMENT 商品 (#PCDATA)>
    <!ATTLIST 商品 商品番号 CDATA #IMPLIED>
]>

<在庫データ>
    <商品 商品番号="TN102">鉛筆</商品>
    <商品>消しゴム</商品>
</在庫データ>

作成した XML 文書を XML Validator でチェックしてみると妥当な XML 文書と表示されました。

#REQUIREDと#IMPLIED(2)

この場合、属性を記述した要素にはそのまま属性が設定され、属性を記述していない要素には属性は何も設定されません。

#REQUIREDと#IMPLIED(3)

デフォルト値の設定

属性が記述されなかった時のデフォルト値を設定する場合は、設定される値をダブルクオーテーションで囲んで記述します。

<!ATTLIST 商品 商品番号 CDATA "AA001">

次の XML 文書を見てください。「商品」要素に対して「商品番号」属性のデフォルト値を設定しています。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品+)>
    <!ELEMENT 商品 (#PCDATA)>
    <!ATTLIST 商品 商品番号 CDATA "AA001">
]>

<在庫データ>
    <商品 商品番号="TN102">鉛筆</商品>
    <商品>消しゴム</商品>
</在庫データ>

この場合、属性を記述した要素にはそのまま属性が設定され、属性を記述していない要素には属性はデフォルト値が設定されます。

デフォルト値の設定(1)

固定値の設定(#FIXED)

常に同じ属性値を設定する場合は、 #FIXED の後に設定される値をダブルクオーテーションで囲んで記述します。この場合、固定値とは異なる属性値を記述するとエラーとなります。属性を省略した場合は固定値が指定されたものとして扱われます。

<!ATTLIST 商品 商品番号 CDATA #FIXED "AA001">

次の XML 文書を見てください。「商品」要素に対して「商品番号」属性の値を固定の"AA001"に設定しています。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品+)>
    <!ELEMENT 商品 (#PCDATA)>
    <!ATTLIST 商品 商品番号 CDATA #FIXED "AA001">
]>

<在庫データ>
    <商品 商品番号="TN102">鉛筆</商品>
    <商品>消しゴム</商品>
</在庫データ>

「商品」要素の「商品番号」属性は必ず "AA001" である必要があるのに 1 つ目の「商品」要素では異なる属性値を設定しているため、作成した XML 文書を XML Validator でチェックしてみるとエラーとなります。

固定値の設定(#FIXED)(1)

今度は「商品」要素に対して「商品番号」属性に固定値を設定しています。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品+)>
    <!ELEMENT 商品 (#PCDATA)>
    <!ATTLIST 商品 商品番号 CDATA #FIXED "AA001">
]>

<在庫データ>
    <商品 商品番号="AA001">鉛筆</商品>
    <商品>消しゴム</商品>
</在庫データ>

作成した XML 文書を XML Validator でチェックしてみると妥当な XML 文書と表示されました。

固定値の設定(#FIXED)(2)

この場合、属性を記述した要素にはそのまま属性が設定され、属性を記述していない要素には固定値が設定されます。

固定値の設定(#FIXED)(3)

属性リスト宣言の属性値の候補を指定する

次に属性値の候補の指定方法を確認します。属性値の候補として指定できるのは次の 6 種類です。

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

CDATA
(値1|値2|...)
ID
IDREF、 IDREFS
NMTOKEN、 NMTOKENS
ENTITY、 ENTITIES

それでは順に確認していきます。

属性値に任意のテキストを記述する(CDATA)

属性値の候補として CDATA を指定した場合には属性値に任意のテキストを設定することができます。

<!ATTLIST 商品 概略 CDATA #IMPLIED>

次の XML 文書を見てください。「商品」要素に対する「概略」属性の属性値の候補として CDATA を設定しています。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品+)>
    <!ELEMENT 商品 (#PCDATA)>
    <!ATTLIST 商品 概略 CDATA #IMPLIED>
]>

<在庫データ>
    <商品 概略="10本で1セット">鉛筆</商品>
    <商品 概略="納期に時間がかかる">消しゴム</商品>
</在庫データ>

ブラウザで表示してみると次のように表示されます。

属性値に任意のテキストを記述する(CDATA)(1)

属性値に列挙した値から1つを記述する

属性値として列挙した値のいずれか一つと同じ値に限定する場合には次のように記述します。

<!ATTLIST 商品 概略 (値1|値2|...) #IMPLIED>

属性値を指定する場合は、列挙した値の一つである必要があります。属性が省略された場合のデフォルト値の設置と組み合わせて使用する場合は次のようになります。

<!ATTLIST 商品 概略 (値1|値2|...) "値1">

次の XML 文書を見てください。「商品」要素に対する「概略」属性の属性値の候補として値を列挙して設定しています。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品+)>
    <!ELEMENT 商品 (#PCDATA)>
    <!ATTLIST 商品 商品色 (赤|青|白) "青">
]>

<在庫データ>
    <商品 商品色="赤">鉛筆</商品>
    <商品 >消しゴム</商品>
</在庫データ>

ブラウザで表示してみると次のように表示されます。属性が省略された場合はデフォルト値が設定されています。

属性値に列挙した値から1つを記述する(1)

今度は列挙した値にない値を属性値に設定してみます。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品+)>
    <!ELEMENT 商品 (#PCDATA)>
    <!ATTLIST 商品 商品色 (赤|青|白) "青">
]>

<在庫データ>
    <商品 商品色="黒">鉛筆</商品>
    <商品 >消しゴム</商品>
</在庫データ>

「商品」要素の「商品色」属性の値は「赤」「青」「白」のいずれかである必要があるのに「黒」を設定しているため、作成した XML 文書を XML Validator でチェックしてみるとエラーとなります。

属性値に列挙した値から1つを記述する(2)

属性値に他と重複しない値を指定する(ID)

属性値に他と重複した値は設定できないようにする場合には、属性値の候補に ID を記述します。

<!ATTLIST 商品 概略 ID #IMPLIED>

同じ属性だけでなく XML 文書内で ID が記述されている属性全てで属性値が同一にならないように記述する必要があります。また ID を記述した場合には、属性値に使用できる文字の種類が要素名や属性名で使用できる文字と同じルールになります。

1文字目:
アルファベット、漢字、ひらがな、カタカナ、アンダーバー(_)、セミコロン(:)

2文字目以降:
1文字目で使用できる文字に加えて、数字、ドット(.)、ハイフン(-)

属性値の候補に ID を記述した場合、属性値は数字から始まる値は設定できません。

次の XML 文書を見てください。「商品」要素に対する「コード」属性の属性値の候補として ID を設定しています。デフォルト値として #REQUIRED を指定した場合は必ず属性を記述する必要がありますが、 #IMPLIED を指定した場合には属性を省略できます。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品+)>
    <!ELEMENT 商品 (#PCDATA)>
    <!ATTLIST 商品 コード ID #IMPLIED>
]>

<在庫データ>
    <商品 コード="AE012">鉛筆</商品>
    <商品 コード="DA521">ボールペン</商品>
    <商品 >消しゴム</商品>
    <商品 >ハサミ</商品>
</在庫データ>

属性の記述を省略した要素が複数あっても問題はありません。作成した XML 文書を XML Validator でチェックしてみると妥当な XML 文書と表示されました。

属性値に他と重複しない値を指定する(ID)(1)

今度は ID が設定された属性に対して、重複する属性値を設定してみます。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品+)>
    <!ELEMENT 商品 (#PCDATA)>
    <!ATTLIST 商品 コード ID #IMPLIED>
]>

<在庫データ>
    <商品 コード="AE012">鉛筆</商品>
    <商品 コード="DA521">ボールペン</商品>
    <商品 コード="AE012">消しゴム</商品>
</在庫データ>

「商品」要素の「コード」属性の値は他と重複していないユニークな値である必要があるのに複数の要素で同じ属性値が設定されているため、作成した XML 文書を XML Validator でチェックしてみるとエラーとなります。

属性値に他と重複しない値を指定する(ID)(2)

属性値の候補にIDを設定した要素を参照する(IDREF, IDREFS)

属性値の候補に IDREF または IDREFS を記述すると、同じ XML 文書内で属性値の候補に ID を記述した要素を参照することができます。

<!ATTLIST 社員 支社コード IDREF #IMPLIED>
<!ATTLIST 社員 支社コード IDREFS #IMPLIED>

次の XML 文書を見てください。「支社」要素に対する「コード」属性の属性値の候補として ID を設定しています。そして「社員」要素に対する「支社コード」属性の値の候補として IDREF を設定しています。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 社員データ[
    <!ELEMENT 社員データ (社員*, 支社*)>
    <!ELEMENT 社員 (#PCDATA)>
    <!ATTLIST 社員 支社コード IDREF #REQUIRED>
    <!ELEMENT 支社 (#PCDATA)>
    <!ATTLIST 支社 コード ID #REQUIRED>
]>

<社員データ>
    <社員 支社コード="B02">山田 太郎</社員>
    <社員 支社コード="B01">近藤 次郎</社員>
    <社員 支社コード="B03">鈴木 花子</社員>
    <社員 支社コード="B01">岸 三郎</社員>
    <支社 コード="B01">本社</支社>
    <支社 コード="B02">大阪支社</支社>
    <支社 コード="B03">名古屋支社</支社>
</社員データ>

IDREF が設定された属性の属性値には、 ID が設定された属性の属性値を設定します。今回の場合であれば ID が設定された属性は「支社」要素の「コード」属性ですので、「社員」要素の「支社コード」属性の値には「支社」要素の「コード」属性の値である「B01」や「B02」などを記述することになります。

「社員」要素では「支社」要素を参照していますが、作成した XML 文書をブラウザで見てみると参照先の値で参照元を置き換えるようなことはしないようです。

属性値の候補にIDを設定した要素を参照する(IDREF, IDREFS)(1)

なお属性値の候補として IDREF ではなく IDREFS を記述すると複数の要素を参照することができます。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 社員データ[
    <!ELEMENT 社員データ (社員*, 支社*)>
    <!ELEMENT 社員 (#PCDATA)>
    <!ATTLIST 社員 支社コード IDREFS #REQUIRED>
    <!ELEMENT 支社 (#PCDATA)>
    <!ATTLIST 支社 コード ID #REQUIRED>
]>

<社員データ>
    <社員 支社コード="B01 B02">山田 太郎</社員>
    <社員 支社コード="B01">近藤 次郎</社員>
    <社員 支社コード="B03 B01">鈴木 花子</社員>
    <社員 支社コード="B01">岸 三郎</社員>
    <支社 コード="B01">本社</支社>
    <支社 コード="B02">大阪支社</支社>
    <支社 コード="B03">名古屋支社</支社>
</社員データ>

複数の要素を参照する場合は、属性値で参照先の属性値を記述する時にスペースを挟んで複数記述してください。

属性値に名前トークンを記述する(NMTOKEN, NMTOKENS)

属性値に名前トークンで許可された文字を使った値を設定できるようにする場合には、属性値の候補に NMTOKEN または NMTOKENS を記述します。

<!ATTLIST 商品 概略 NMTOKEN #IMPLIED>
<!ATTLIST 商品 概略 NMTOKENS #IMPLIED>

名前トークンで許可された文字というのは、要素名や属性名で使用できる文字の 2 文字目以降で使用することが許可されている文字です。具体的には次の文字となります。

アルファベット、漢字、ひらがな、カタカナ、アンダーバー(_)、セミコロン(:)、数字、ドット(.)、ハイフン(-)

属性値の候補に ID を記述した場合、属性値は数字から始まる値は設定できませんが、 NMTOKEN を記述した場合は数字から始まる値も設定可能です。そして NMTOKEN を記述した場合は使用できる文字に制限が発生する以外に他には制限はありません。属性値として重複する値を設定することもできます。

次の XML 文書を見てください。「製品」要素に対する「製品コード」属性の属性値の候補として NMTOKEN を記述しています。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 製品データ[
    <!ELEMENT 製品データ (製品+)>
    <!ELEMENT 製品 (#PCDATA)>
    <!ATTLIST 製品 製品コード NMTOKEN #IMPLIED>
]>

<製品データ>
    <製品 製品コード="257A">自転車</製品>
    <製品 製品コード="368C">テント</製品>
    <製品 製品コード="914D">カバン</製品>
</製品データ>

NMTOKEN が記述された属性に対しては属性値として数字から始める値も記述できます。作成した XML 文書をブラウザで表示してみると次のように表示されます。

属性値に名前トークンを記述する(NMTOKEN, NMTOKENS)(1)

なお属性値の候補として NMTOKEN ではなく NMTOKENS を記述すると複数の値をスペースで区切って属性値に記述することができます。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 製品データ[
    <!ELEMENT 製品データ (製品+)>
    <!ELEMENT 製品 (#PCDATA)>
    <!ATTLIST 製品 製品コード NMTOKENS #IMPLIED>
]>

<製品データ>
    <製品 製品コード="257A 259E">自転車</製品>
    <製品 製品コード="368C">テント</製品>
    <製品 製品コード="914D 903A 945C">カバン</製品>
</製品データ>

名前トークンではスペースは使用できませんが、 NMTOKEN を記述している場合は値の区切りとして使用することができます。

属性値に実体宣言した値を記述する(ENTITY, ENTITIES)

XML では & を &amp; のように記述する実体参照が利用できますが、あらかじめ用意された 5 つの実体参照だけではなく、任意の文字列を実体として登録し参照することができます。(参考:「実体参照」)。

実体は要素の内容などから参照できますが、属性値として参照する場合には属性値の候補に ENTITY または ENTITIES を記述します。(要素の内容から参照する方法についてはあとで解説します)。

<!ATTLIST 商品 概略 ENTITY #IMPLIED>
<!ATTLIST 商品 概略 ENTITIES #IMPLIED>

次の XML 文書を見てください。「製品」要素に対する「画像」属性の属性値の候補として ENTITY を記述しています。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 製品データ[
    <!ELEMENT 製品データ (製品+)>
    <!ELEMENT 製品 (#PCDATA)>
    <!ATTLIST 製品 画像 ENTITY #REQUIRED>
    <!NOTATION png SYSTEM "png">
    <!ENTITY 時計画像 SYSTEM "watch.png" NDATA png>
    <!ENTITY 眼鏡画像 SYSTEM "glasses.png" NDATA png>
]>

<製品データ>
    <製品 画像="時計画像">時計</製品>
    <製品 画像="眼鏡画像">眼鏡</製品>
</製品データ>

作成した XML 文書をブラウザで表示してみると次のように表示されます。属性の値を参照先の実体で置き換えるようなことはしないようです。

属性値に実体宣言した値を記述する(ENTITY, ENTITIES)(1)

このサンプルでは画像ファイルの URI を実体として登録しています。画像ファイルのように XML とは異なるデータの場合、解析対象外エンティティと呼ばれます。 XML では画像ファイルなのかそれとも全然別のデータファイルなのかなどは関知しないのですが、どのようなデータ型なのかが分かるようにしておく必要があり、次のような記述を行います。

<!NOTATION notation名 SYSTEM "システム識別子">

"システム識別子"には JPEG 画像なら "jpg" とか "jpeg" 、 PNG 画像なら "png" のように記述します(このファイル形式ならこの名前という決まりは特にないので一般的な値を記述しておけば構いません)。そして notation名 にも任意の名前を記述します。

次にファイルの URI に対して実体名を登録する時に、最後に「NDATA notation名」を付け加えます。

<!ENTITY 実体名 SYSTEM "ファイルのURI" NDATA notation名>

これで要素の属性で属性値として実体名を記述することで対応するファイルのURIを参照することができるようになります。

なお属性値の候補として ENTITY ではなく ENTITIES を記述すると複数の値をスペースで区切って属性値に記述することができます。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 製品データ[
    <!ELEMENT 製品データ (製品+)>
    <!ELEMENT 製品 (#PCDATA)>
    <!ATTLIST 製品 画像 ENTITIES #REQUIRED>
    <!NOTATION png SYSTEM "png">
    <!ENTITY 時計画像1 SYSTEM "watch1.png" NDATA png>
    <!ENTITY 時計画像2 SYSTEM "watch2.png" NDATA png>
    <!ENTITY 眼鏡画像 SYSTEM "glasses.png" NDATA png>
]>

<製品データ>
    <製品 画像="時計画像1 時計画像2">時計</製品>
    <製品 画像="眼鏡画像">眼鏡</製品>
</製品データ>

実体宣言の記述方法

文書型宣言の中には要素型宣言や属性リスト宣言の他に実体宣言を記述することができます。実体宣言とは特定の文字列やファイルに対して実体名を定義することです。 XML 文書の中で繰り返し使われるようなテキストをそのまま記述する代わりに実体名を使って記述することができます。

<!ENTITY 実体名 "文字列">

実体宣言で記述された実体名は、 XML 文書内で &実体名; と記述することで参照することができるようになります。

なお実体名に使用できる文字の種類は要素名や属性名で使用できる文字と同じで次のようなルールがあります。数字から始まる値は指定できません。

1文字目:
アルファベット、漢字、ひらがな、カタカナ、アンダーバー(_)、セミコロン(:)

2文字目以降:
1文字目で使用できる文字に加えて、数字、ドット(.)、ハイフン(-)

それでは実体宣言の記述方法と XML 文書の中から実体を参照する方法の記述の仕方について見ていきます。

文字列と実体名を結びつける

最初に文字列に対して実体名を結びつける方法です。書式は次のとおりです。

<!ENTITY 実体名 "文字列">

例えば "東京都港区赤坂4丁目" という文字列に対して「住所」という実体名を宣言する場合は次のように記述します。

<!ENTITY 住所 "東京都港区赤坂4丁目">

実体制限を記述する場所は要素型宣言や属性リスト宣言と同じく文書型宣言の中に記述します。次の XML 文書を見てください。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品+)>
    <!ELEMENT 商品 (名前, 保管場所)>
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT 保管場所 (#PCDATA)>
    <!ENTITY 住所 "東京都港区赤坂4丁目">
]>

<在庫データ>
    <商品>
        <名前>自転車</名前>
        <保管場所>&住所;</保管場所>
    </商品>
    <商品>
        <名前>花瓶</名前>
        <保管場所>&住所;</保管場所>
    </商品>
</在庫データ>

文書型宣言の中の中で実体名として「住所」を宣言しています。そして XML 文書の中で「&住所;」として参照しています。この XML ファイルをブラウザで表示してみると次のように表示されます。

文字列と実体名を結びつける(1)

「&住所;」と記述したところが実体である "東京都港区赤坂4丁目" に置き換わって表示されているのが確認できます。

ファイルと実体名を結びつける

また文字列だけでなく別に作成したファイルに対して実体名を定義することもできます。 XML 文書の中で実体名が記述されると、実体であるファイルに記述されている内容に置き換えられます。ファイルを指定する場合は次のような形式となります。

<!ENTITY 実体名 SYSTEM "ファイルのURI">

ファイルの URI は、実体であるファイルと参照する XML ファイルが同じサーバに設置されている場合は相対パスで記述できます。

<!ENTITY 追加データ SYSTEM "newdata.xml">

別のサーバに設置されている場合は次のような形式で記述できます。

<!ENTITY 追加データ SYSTEM "https://www.example.jp/file/newdata.xml">

実体制限を記述する場所は要素型宣言や属性リスト宣言と同じく文書型宣言の中に記述します。次の XML 文書を見てください。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品+)>
    <!ELEMENT 商品 (名前, 色)>
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT 色 (#PCDATA)>
    <!ENTITY 追加データ SYSTEM "newdata.xml">
]>

<在庫データ>
    <商品>
        <名前>自転車</名前>
        <色>黒</色>
    </商品>
    <商品>
        <名前>花瓶</名前>
        <色>白</色>
    </商品>
    &追加データ;
</在庫データ>

文書型宣言の中の中で実体名として「追加データ」を宣言しています。そして XML 文書の中で「&追加データ;」として参照しています。そして別ファイルとして次のような内容の XML ファイルを先ほどのファイルと同じディレクトリに "newdata.xml" という名前で設置しました。

<?xml version="1.0" encoding="UTF-8" ?>

<商品>
    <名前>カーテン</名前>
    <色>黄色</色>
</商品>

元の XML ファイルをブラウザで表示してみると次のように表示されます。

ファイルと実体名を結びつける(1)

「&追加データ;」と記述したところが実体であるファイルの中身に置き換わって表示されると思われたのですが、何も表示されませんでした。原因は現時点では不明なので分かり次第更新します。

DTDを別のファイルに分ける

ここまで DTD を対象となる XML 文書の中に直接記述してきました。 DTD が単一のファイルでのみ使われる場合はいいのですが、複数の XML 文書で同じ DTD を使用したい場合、 DTD だけを別のファイルに分けて記述しておき複数の XML ファイルから同じ DTD のファイルを読み込んで使用するようにすると便利です。

次のような XML 文書を例に考えてみます。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ[
    <!ELEMENT 在庫データ (商品+)>
    <!ELEMENT 商品 (名前, 個数)>
    <!ELEMENT 名前 (#PCDATA)>
    <!ELEMENT 個数 (#PCDATA)>
]>

<在庫データ>
    <商品>
        <名前>自転車</名前>
        <個数>20</個数>
    </商品>
</在庫データ>

共通して利用する DTD 部分を次のように別の XML ファイルに保存します。ファイル名は "mydtd.xml" としました。

<?xml version="1.0" encoding="UTF-8" ?>

<!ELEMENT 在庫データ (商品+)>
<!ELEMENT 商品 (名前, 個数)>
<!ELEMENT 名前 (#PCDATA)>
<!ELEMENT 個数 (#PCDATA)>

次に XML 文書から外部のファイルに分けた DTD を読み込みます。外部ファイルに分けた DTD を使用する場合、文書型宣言は次のような書式となります。

<!DOCTYPE ルート要素名 SYSTEM "DTDファイルのURI">

先ほどの XML 文書を外部のファイルに分けた DTD を読み込むように変更します。

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE 在庫データ SYSTEM "mydtd.xml">

<在庫データ>
    <商品>
        <名前>自転車</名前>
        <個数>20</個数>
    </商品>
</在庫データ>

それでは変更した XML 文書を XML Validator でチェックしてみると妥当な XML 文書と表示されました。

DTDを別のファイルに分ける(1)

確認のために DTD が記述されている XML ファイルで「個数」となっていた部分を「在庫」に変更してエラーがでるようにしてみます。

<?xml version="1.0" encoding="UTF-8" ?>

<!ELEMENT 在庫データ (商品+)>
<!ELEMENT 商品 (名前, 在庫)>
<!ELEMENT 名前 (#PCDATA)>
<!ELEMENT 在庫 (#PCDATA)>

その後で改めて XML 文書を XML Validator でチェックしてみると次のようにエラーが表示されました。

DTDを別のファイルに分ける(2)

外部ファイルに記述した DTD が XML 文書の方で読み込まれていることが確認できました。

-- --

ルールの定義を行う言語のひとつである DTD(Document Type Definition) に関する解説と、 DTD を使った XML 文書の構造を定義する方法について解説しました。

( Written by Tatsuo Ikura )

関連記事 (一部広告含む)
Profile
profile_img

著者 / TATSUO IKURA

初心者~中級者の方を対象としたプログラミング方法や開発環境の構築の解説を行うサイトの運営を行っています。