子要素の指定


1つの子要素を指定する

ルート要素は、一般に考えられる全ての子要素を持つことができますが
それでも、ANY キーワードを指定することは、文書の構造を曖昧にしてしまいます
例えば、title 要素は文書の表題を表すものと考えることができますが
この title 要素が複数指定されても良い文書は、良い構造と呼ぶことはできません

文書の作成日や、表題等を表す要素は、1つ以上を指定できないようにするべきです
DTD では、それぞれの要素に、持つことができる子要素を指定することができます
子要素を指定するには、要素型宣言の内容記述部に、子要素命を括弧 ( ) で囲んで指定します
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE object [
	<!ELEMENT object (title)>
	<!ELEMENT title (#PCDATA)>
]>
<object>
	<title>Kitty on your lap</title>
</object>
この文書の DTD は、object 要素が title という子要素を持つことを表しています
妥当な XML 文書の場合、object 要素は title 以外の要素やデータをもつことはできません

また、object 要素は必ず title を含まなければいけません
子要素を指定している以上、その要素は必須となります
object 要素が title を省略した場合、文書は妥当ではなくなります


複数の子要素を指定する

ある要素が、複数の要素を子として持つことができる場合
それぞれの要素をカンマで区切って括弧に指定します
このような、カンマで区切った子要素のリストを列リストと呼びます

列リストで列挙された、包括可能な要素群は
必ず左から列挙順で指定しなければなりません
例えば、DTD の要素型宣言で (a , b) と指定されていた場合
XML 文書では、要素 a が b よりも先に指定されなければならないのです
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE object [
	<!ELEMENT object (title , copyright)>
	<!ELEMENT title (#PCDATA)>
	<!ELEMENT copyright (#PCDATA)>
]>
<object>
	<title>Kitty on your lap</title>
	<copyright>Leon Akasaka</copyright>
</object>
この文書の object ルート要素は、title 要素と copyright 要素を持つことを宣言しています
これによって、object 要素は指定された複数の子要素を持つことができます
もちろん、object は title も copyright も省略することはできません
また、title 要素と copyright 要素の位置を入れ替えることもできません
object 要素において、title 子要素は copyright 子要素よりも先に指定されなければならないのです

object 要素が、同一の要素を複数保持したいのであれば
列リストに、子要素として含むべき要素を、その数だけ指定します
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE object [
	<!ELEMENT object (kitty , kitty)>
	<!ELEMENT kitty (#PCDATA)>
]>
<object>
	<kitty>Kitty on your lap</kitty>
	<kitty>Tokyo mew mew</kitty>
</object>
この文書は、object ルート要素が kitty 要素を2つ持たなければならないことを表しています
DTD の object 要素型宣言の列リストを見れば、それがよくわかりますね


柔軟な要素指定

上記した方法で、1つの要素、または複数の要素を子要素として持つことができようになりますが
この方法では、要素を省略したり、自由な数の子要素を指定することはできません

HTML における TABLE 要素の子要素 TR や TH のように
必要に応じて自由な数だけ、必要な子要素を指定したい場合があるでしょう
このような要素を宣言するには、子要素リストの要素名の末尾に記号をつけます

0 個以上の子要素を宣言するにはアスタリスク * 記号を使います
末尾にアスタリスクが指定されているリスト内の子要素は
その要素が、必要に応じて自由にその子要素を持つことができることを表します
省略してもかまいませんし、10 個指定してもかまわないことを意味します
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE object [
	<!ELEMENT object ANY>
	<!ELEMENT document (text*)>
	<!ELEMENT text (#PCDATA)>
]>
<object>
	<document>
		<text>Kitty on your lap</text>
		<text>Tokyo mew mew</text>
		<text>Magical nyan nyan TARUTO</text>
	</document>
	<document />
</object>
この文書は、微妙ですが妥当な文書です
document 要素は、0 個以上の text 要素を含むことを表しています
text 要素は、必要なだけ指定できますし、不用なら省略もできます

ただし、document 要素は空要素ではないので
正確には、空タグとして指定することは正しいとは言えないかもしれません
そのため、XML パーサーは妥当性を検証する時、警告を発するかもしれません

最低でも 1 つ以上を指定しなければ行けないようなケースでは
* 記号ではなく プラス記号 + を子要素リストで指定した要素の末尾に指定します
この場合、1 つ以上はその要素を子要素として指定しなければなりません
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE object [
	<!ELEMENT object ANY>
	<!ELEMENT document (text+)>
	<!ELEMENT text (#PCDATA)>
]>
<object>
	<document>
		<text>Kitty on your lap</text>
		<text>Tokyo mew mew</text>
		<text>Magical nyan nyan TARUTO</text>
	</document>
	<document>
		<text>Di Gi Charat</text>
	</document>
</object>
この場合、document 要素は 1 つ以上の text 要素を持たなければなりません
先ほどのように省略すると、文書は妥当ではなくなります


省略、または1つの子要素

子要素を自由な数だけ指定できるというのは便利ですが
省略しても良いが、1つ以上を指定してはならないという要素もあるでしょう

例えば、表題などがそうです
表題がなく、いきなり本文を書き始めても、文書が成り立たないわけではありません
しかし、表題が複数あっては、どれが表題なのかわかりません
となれば、表題を表す要素は、省略されるか1つのみがもっとも好ましいと考えられるでしょう

このような要素を宣言するには、子要素リストで、要素名の末尾に疑問符 ? を指定します
こうすれば、その子要素は1つだけを指定するか、または省略可能となるでしょう
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE object [
	<!ELEMENT object ANY>
	<!ELEMENT document (title? , text+)>
	<!ELEMENT title (#PCDATA)>
	<!ELEMENT text (#PCDATA)>
]>
<object>
	<document>
		<title>Kitty on your lap</title>
		<text>This work is very interesting!</text>
	</document>
	<document>
		<text>Magical nyan nyan TARUTO is cute!</text>
	</document>
</object>
document 要素は、title 要素を1つだけ指定することができます
もちろん、疑問符 ? が DTD で指定されているので、省略も可能です
ただし、1つ以上を指定した場合は妥当な文書ではなくなってしまいます



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