RELAX NG Compact Syntax Tutorial を読む(2)
"RELAX NG Compact Syntax Tutorial" をだらだらと読んでいくの巻。第 2 章は "2. Choice" です。
例として挙げられているアドレス帳XMLインスタンス。
<addressBook> <card> <givenName>John</givenName> <familyName>Smith</familyName> <email>js@example.com</email> </card> <card> <name>Fred Bloggs</name> <email>fb@example.net</email> </card> </addressBook>
- 最初の card の「名前」は givenName 要素と familyName 要素の 2 で表現されている。名が givenName 要素で、姓が familyName 要素。
- 次の card の「名前」は name 要素 1 つで表されている。
このように「name 要素」または「givenName 要素と familyName 要素」というパターンは次のように書く。
element addressBook { element card { (element name { text } | (element givenName { text }, element familyName { text })), element email { text }, element note { text }? }* }
見にくいので中の card の部分だけ、「element」とか「{...}」をどけて抜き出してみると、こんな感じ
element card { (name | (givenName, familyName)), email, ... }
というわけで、choice パターンは「(A | B)」のようにカッコと「|」記号とを使って書く。「givenName 要素と familyName 要素をこの順番で」ってところも「(givenName, familyName)」とカッコでくくられている。
DTD ではこんな感じ。カッコ「()」と「|」記号を使っているのは一緒。
<!DOCTYPE addressBook [ <!ELEMENT addressBook (card*)> <!ELEMENT card ((name | (givenName, familyName)), email, note?)> <!ELEMENT name (#PCDATA)> <!ELEMENT email (#PCDATA)> <!ELEMENT givenName (#PCDATA)> <!ELEMENT familyName (#PCDATA)> <!ELEMENT note (#PCDATA)> ]>
カッコを忘れずに。2 章の最後に書いてあるけど、
x | y, z
という書き方はできなくて、
(x | y), z
か、
x | (y, z)
というふうに、何と何が choice なのかを明示する必要がある。