属性型


列挙型

属性の型は CDATA だけではありません
多くの場合、属性型は CDATA だけで十分だと思いますが
場合によっては、特にプログラムで処理する側から見ると、他の型も必要となります

もし、属性で指定する値があらかじめ決まっていたらどうでしょうか
CDATA では、作者が属性に何を指定するかは #FIXED を除いて束縛できません
何を思ったか、作者は sex 属性に "両性具有"と入力するかもしれません
しかし、CDATA を指定している以上、これを制限することはできないでしょう

sex (性別)属性には、male (男性) か female (女性) のいずれかを指定するべきであり
これ以外の適当な値を入力されることを、プログラムは望まないでしょう
このような場合は、指定したいくつかのキーワードのみを入力できるようにするべきです
これを実現するには列挙型を用いる必要があります

列挙型は、属性宣言の属性型の部分に、キーワードではなくリストを指定します
リストは、要素型宣言と同じく、括弧で ( ) 囲んでキーワードを列挙します
それぞれのキーワードは、縦バー | で区切ります
デフォルト値は、必ず列挙されたキーワードのうちのいずれかでなければなりません
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE object [
	<!ELEMENT object (nekomimi*)>
	<!ELEMENT nekomimi EMPTY>
	<!ATTLIST nekomimi
		name CDATA #IMPLIED
		sex (male | female) #REQUIRED
	>
]>

<object>
	<nekomimi name="Rena" sex="female" />
	<nekomimi name="Kaimu" sex="male" />
</object>
この文書の nekomimi 属性には、name 属性と sex 属性があります
sex 属性は列挙型なので、female まはた make 以外を指定することはできません
このような性質の情報は、子要素にするよりも属性の方が向いているといえるでしょう

sex 属性に列挙されたキーワード以外を指定した場合
XML パーサは妥当ではないと判断します


XML 命名規則

XML における識別子の命名規則は、プログラムの識別子命名規則に似ています
これは偶然ではなく、プログラムにとって、この命名規則が標準的なのです

属性の情報が、何らかの識別子の命名を要求するものである場合
プログラムは CDATA で受けとって、これを解析するよりも
属性型で制限して、無効な名前の場合は妥当ではないと判断したほうが効率的です

属性型で NMTOKEN 属性型を指定すれば
属性の値は、XML の命名規則に従った有効な名前でなければいけません
無効な名前を指定した場合は、XML パーサが妥当ではないと判断するでしょう
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE object [
	<!ELEMENT object (lang)>
	<!ELEMENT lang (#PCDATA)>
	<!ATTLIST lang var NMTOKEN #IMPLIED>
	
]>

<object>
	<lang var="strText">
		strText = "Kitty on your lap";
		MsgBox(strText , MB_OK);
	</lang>
</object>
この文書は、仮想言語を表す要素 lang を持っているとしましょう
lang は、仕様からコード内で用いられる自動変数は var 属性で宣言するものとします
変数名は XML の命名規則に従わなければならないので
数値だけ識別子や、適当な記号を用いた変数などを宣言することはできないでしょう

しかし、この文書の仮想言語は大きな欠点を持っています
XML の命名規則に従うため、属性はホワイトスペースを持てません
すなわち、どうあがいても変数を一つしか宣言することができないということです

これは、複数の識別子を一度に指定させたい場合に障害となるでしょう
このような場合は NMTOKENS 属性型を指定します
こうすることで、値を空白で区切りることで複数指定することができるようになります
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE object [
	<!ELEMENT object (lang)>
	<!ELEMENT lang (#PCDATA)>
	<!ATTLIST lang var NMTOKENS #IMPLIED>
	
]>

<object>
	<lang var="strText iCheck">
		strText = "Kitty on your lap";
		iCheck = MsgBox(strText , MB_YESNO);
		if (iCheck == IDNO) return -1;
	</lang>
</object>
lang 要素の var 属性は NMTOKENS 型なので
属性値で指定する名前は、それぞれを空白で区切ることで複数指定することができます


要素識別値

プログラムから、特定の要素を制御する場合
要素に一意な名前をつけ、プログラムからオブジェクトにアクセスする必要があります

このような場合、要素に付けられている識別用の ID は
他の要素につけられている識別子と衝突してはならないという条件があります
これを解決するためには ID 属性型を用います

ID 型属性値は、同一文書内で同じ ID を2回使うことはできず
ID に用いる識別子も XML の命名規則に従ったものでなければいけません
これに反した場合 XML パーサは妥当ではないとしてエラーを出すでしょう
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE object [
	<!ELEMENT object (image*)>
	<!ELEMENT image EMPTY>
	<!ATTLIST image 
		src CDATA #REQUIRED
		id ID #IMPLIED
	>	
]>

<object>
	<image src="http://www.***" id="Kitty1" />
	<image src="http://www.***" id="Kitty2" />
</object>
この文書の image 要素は、外部実体のアドレスを指定する src 属性と
この画像オブジェクトに対する id 属性を指定することができます
例えば、プログラムはこの id 属性の識別子を通してオブジェクトにアクセスし
画像を別の画像ファイルに動的に変化させたり、ファイルの情報を得たりすることができるでしょう

因みに、id 属性の "Kitty2" という値を "Kitty1" に替えてみると
上の id 属性と識別子が衝突するので、パーサはエラーを出します

逆に、属性で要素の ID を指定するというケースも考えられます
例えば、その要素が表すコンポーネントの親子関係を明示する場合などです
このような場合は IDREF 属性型を使用します

IDREF 型の属性には、すでに定義されている要素の識別子以外を指定することはできません
この属性は、必ず定義済みの要素識別子が入ります
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE object [
	<!ELEMENT object (image)*>
	<!ELEMENT image EMPTY>
	<!ATTLIST image 
		src CDATA #REQUIRED
		id ID #IMPLIED
		add IDREF #IMPLIED
	>
]>

<object>
	<image src="http://www.***" id="Kitty1" />
	<image src="http://www.***" add="Kitty1" />
</object>
この文書の image 要素は、他の image 要素に加算することができるものとします
add 要素で他の image 要素の識別子を指定すれば
指定した画像と関連付けられる、というようなプログラムの処理を期待できるでしょう
IDREF を用いれば、このような要素間の関連付けができるようになります


実体属性

属性値に、XML の設計者が指定する確実な実体を入力させたい場合
ENTITY 属性型を使用することで、これを強制することができます

この属性によって、外部一般実体をリンクすることができるようになります
もちろん、その外部のバイナリデータをどう処理するかは、プログラムの仕事です
これは XML 文書に他の形式のデータを組み込む方法の一つです
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE object [
	<!ENTITY KITTY SYSTEM "kitty.jpg">

	<!ELEMENT object (image)*>
	<!ELEMENT image EMPTY>
	<!ATTLIST image src ENTITY #REQUIRED>
]>

<object>
	<image src="KITTY" />
</object>
この文書の image 要素の src 属性は ENTITY 型です
この属性値には、有効な外部実体参照を指定しなければエラーとなります

複数の実体を同時に指定したい場合は ENTITIES 属性型を使います
この場合、属性値で指定する実体名は、それぞれ空白で区切ります
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE object [
	<!ENTITY RENA SYSTEM "rena.jpg">
	<!ENTITY YUKI SYSTEM "yuki.jpg">
	<!ENTITY MIMI SYSTEM "mimi.jpg">

	<!ELEMENT object (image)*>
	<!ELEMENT image EMPTY>
	<!ATTLIST image src ENTITYS #REQUIRED>
]>

<object>
	<image src="RENA YUKI MIMI" />
</object>



前のページへ戻る次のページへ