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

要素型宣言は XML 文書の中に含まれる要素の名前や出現する回数などを定義したものでしたが、属性リスト宣言は要素に記述される属性について定義したものになります。ここでは属性型宣言の記述方法について解説します。

(Last modified: )

属性リスト宣言の形式

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

<!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">時計</製品>
    <製品 画像="眼鏡画像">眼鏡</製品>
</製品データ>

-- --

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

( Written by Tatsuo Ikura )

プロフィール画像

著者 / TATSUO IKURA

これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。