RELAX NG

XMLスキーマ


XMLスキーマって何?Wikipediaによると


XMLSGML等で文書を作成する際、その文書構造を定義する言語を言う。
ということです。

Document Type Definition


略してDTDスキーマ言語のひとつ。元々SGMLスキーマ言語として開発され、SGMLから派生したXMLにおいても、スキーマ言語として採用されていました。しかし現在では、XMLスキーマ言語としてDTDを利用するケースは少なくなっているようです。XMLが勧告された後、DTDに対して

  • XMLの文法とは異なる文法を採用している
  • XML名前空間に対応していない

などの問題が指摘されてきました。

RELAX NG


ラクシング。DTDに代わるXMLの新たなスキーマ言語のひとつ。RELAX NGで記述されたスキーマは、それ自身がXML文書となっています。RELAX NGスキーマXML文書として記述する方法を、XML構文といいます。RELAX NGでは、スキーマを簡潔な短縮構文(Compact Syntax)で記述することもできます。

たとえば、電子メールのアドレス帳を表現した簡単な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>

これに対応するRELAX NGXML構文は次のように書くことができます。

<element name="addressBook" xmlns="http://relaxng.org/ns/structure/0.9">
  <zeroOrMore>
    <element name="card">
      <element name="name">
        <text/>
      </element>
      <element name="email">
        <text/>
      </element>
    </element>
  </zeroOrMore>
</element>

一方、これに対応するRELAX NGの短縮構文は次のように書くことができます。

element addressBook {
  element card {
    element name { text },
    element email { text }
  }*
}

短縮構文の方が見通しが良いですね。
Google XML Document Format Style Guide(日本語訳はこちら)ではXMLスキーマ言語としてRELAX NGのcompact syntaxを使うべきであるとしています。

Validator


XMLスキーマはただXMLの文書構造を定義するためのものではなく、Validator(妥当性検証器)への入力とすることで作成したXML文書の妥当性を検証することができます。
RELAX NGのValidatorには次のようなものがあります。

Jing
RELAX NGの設計者のひとりであるジェームズ・クラーク氏が開発したValidator。XML syntax、compact syntaxの両方に対応している。
RNV
ANSI Cによる実装。compact syntaxにのみ対応している。
Libxml2
GNOMEプロジェクト。XML syntaxのみ対応。

Jing


で検証してみます。
今回は一冊の書籍を記述するための簡単なXML文書のためのスキーマを例に行います。一冊の書籍を記述するXML文書インスタンスは以下の通り。これをsomebook.xmlとします。

<?xml version="1.0" encoding="UTF-8"?>
<book>
  <page>これは1ページです。</page>
  <page>これは2ページです。</page>
</book>

XML syntaxによるスキーマは以下の通り。これをbook.rngとします。

<element name="book" xmlns="http://relaxng.org/ns/structure/1.0">
  <oneOrMore>
    <element name="page">
      <text/>
    </element>
  </oneOrMore>
</element>

compact syntaxによるスキーマは以下の通り。これをbook.rncとします。

element book {
  element page { text }+
}

こちらから適当なバージョンのJingをダウンロードします。展開したディレクトリのbinの中にjing.jarがあるので以下のように検証します。


$ java -jar jing.jar book.rng somebook.xml

$ java -jar jing.jar -c book.rnc somebook.xml
何も出力がなければ妥当だということです。
compact syntaxによるスキーマで検証する場合は-cオプションが必要なので注意。

試しにスキーマは変えずに、以下のようなotherbook.xmlを検証してみた。

<?xml version="1.0" encoding="UTF-8"?>
<!-- Invalid book instance -->
<book>
  <title>これはタイトルです。</title>
  <page>これは1ページです。</page>
  <page>これは2ページです。</page>
</book>

titletという要素はスキーマで定義されていません。これを検証すると次のようにエラーが出ました。


$ java -jar jing.jar book.rng otherbook.xml
otherbook.xml:4:10: error: element "title" not allowed anywhere; expected element "page"

うむ!