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 なのかを明示する必要がある。