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>

これのスキーマDTD で書くとこんな感じだろうと。

<!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”」と後の方で説明されるみたいなので置いておく。

はてな

はてなスーパーpre記法のシンタックスハイライトは、RELAX NG Compact Syntax にも対応している(ファイルタイプとして「rnc」を指定)。
ん、空白以外の文字の後にコメントがあるとおかしい? 上の例だと、「element email { text }」の後のコメント「# an email address」が青くなってない。