要素型宣言の記述方法

広告

要素型宣言で 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)

-- --

要素型宣言の記述方法について解説しました。

( Written by Tatsuo Ikura )

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

著者 / TATSUO IKURA

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