RELAX NG Compact Syntax Tutotial を読む(1)
"RELAX NG Compact Syntax Tutotial" を読む。
まずは最初の "1. Getting started" から。
えー、まず、次のような E-mail アドレス帳の XML 文書があるとする、と。
<addressBook> <card> <name>John Smith</name> <email>js@example.com</email> </card> <card> <name>Fred Bloggs</name> <email>fb@example.net</email> </card> </addressBook>
<!DOCTYPE addressBook [ <!ELEMENT addressBook (card*)> <!ELEMENT card (name, email)> <!ELEMENT name (#PCDATA)> <!ELEMENT email (#PCDATA)> ]>
これの読み方はこんな感じ。
- ドキュメント要素(ルート要素)は "addressBook" ですよ。
- addressBook 要素の内容は card 要素が 0 個以上。
- card 要素の内容は name 要素と email 要素が 1 つずつ、この順番で。
- name 要素の内容は文字列のみ。
- email 要素の内容は文字列のみ。
これを RELAX NG Compact Syntax で書くと次のようになる。
element addressBook { element card { element name { text }, element email { text } }* }
DTD では要素型宣言を並べてたけど、RELAX NG だと入れ子にして書くこともできる。
要素
一番上が addressBook 要素の定義。
element addressBook { ...省略... }
これで「ルート要素は "addressBook"」って定義(DTD だと DOCTYPE 宣言(文書型宣言)のところ)も兼ねているみたい。チュートリアルの後の方で出てくるけど、
grammer { start = element addressBook { ...省略... } }
というふうに「start = 要素」で明示的に書くこともできるみたい。
属性や内容は要素名のあとの「{}」の間に書く。入れ子にもできる。
element addressBook { element card { ...省略... }* }
個数
「0 個以上」ってのは、「}」の後ろの「*」記号で表す。
もし「0 はダメ、1つ以上」にしたい場合は「+」を使う(DTD と同じ記号)。
「0 か 1 か」、optional な場合は「?」記号を使う。チュートリアルでは、card 要素が optional な note 要素を持つ場合として次の例が挙がっている。
element addressBook { element card { element name { text }, element email { text }, element note { text }? }* }
順番
「card 要素の内容は name 要素と email 要素が 1 つずつ、この順番で」というのはDTD 同様に「,」(カンマ)区切りで要素を並べる。
element card { element name { text }, element email { text } }*
文字列
「内容が文字列のみ(他の要素は来ない)」、DTD の #PCDATA 相当なのは「text」パターン。
element name { text }
text パターンは空文字列にもマッチする。
空白
タグとタグの間の whitespace はパターンマッチの際に無視される。例えば最初に挙げたインスタンスの例だと、addressBook の開始タグと card の開始タグの間には改行とインデントのためのスペースがあり、addressBook の内容に text は無いけれども、これは無視される、と。
<addressBook> ←ここで改行 <card> ↑ここにスペース
コメント
コメントには「#」記号を使う。# から行末までがコメントと見なされる。# は行頭になくても良い。
# A RELAX NG compact syntax pattern # for an address book. element addressBook { # an entry in the address book element card { element name { text }, element email { text } # an email address }* }
2 個続きの「##」で始まるコメントは特別扱いされるそうな。詳細は「see Section 13, “Annotations”」と後の方で説明されるみたいなので置いておく。