RELAX NG 仕様書

Committee Specification 3 December 2001

このバージョン:
Committee Specification: 3 December 2001
前のバージョン:
Committee Specification: 11 August 2001
編者:
James Clark <jjc@jclark.com>, 村田 真 <EB2M-MRT@asahi-net.or.jp>
訳者:
小町祐史, 松下電送(株)
川俣晶, (株)ピーデー
山本陽平, リコー(株)
村田真, 国際大学

Copyright © The Organization for the Advancement of Structured Information Standards [OASIS] 2001. All Rights Reserved.

原規定及びその翻訳は,その全体又は一部を,複写し,他に供給してよく,それにコメントしたり,それを別の方法で説明したり,その実装を支援したりする派生物を用意し,その全体又は一部を,複写し,印刷し,配布してもよい。これらの活動には何の制限もないが,前述の著作権表示及びこの段落が,それらのすべての複写及び派生物に含まれることを前提とする。しかし,この規定そのものは,どんな方法でも,例えば著作権表示又はOASISへの参照の削除などによって,決して修正してはならない。その例外は,OASIS規定を開発するために必要な場合であり,その場合は,OASIS Intellectual Property Rights規定に定義される著作権の手続きに従わなければならない。もう一つの例外は,英語以外の言語に翻訳するために必要な場合である。

ここに承認する限定付きの許諾は,永続的であって,OASIS,その後任者又はその譲受人によって撤回されることはない。

この原規定及びそこに含まれる情報は,"そのまま"の状態で提供される。OASISは,ここに示す情報の利用が,商業化又は特定目的への適合のすべての権利又は暗黙の保証を侵害しないことを,どのような形においても,一切保証しない。

注意

この翻訳は,$Date: 2003/07/26 02:00:04 $に作成した。


概要

この規格は,XMLのための簡潔なスキーマ言語RELAX NGを規定する。RELAX NGは、[RELAX]及び[TREX]に基づく。RELAX NGスキーマは,XML文書の構造及び内容に関するパターンを規定する。 RELAX NGスキーマは,それ自体がXML文書になる。

この文書の状態

この委員会規定は,OASIS RELAX NG技術委員会によってその公表が承認された。この規定は安定した文書であって,委員会の合意に基づく。この規定に関するコメントは,relax-ng-comment@lists.oasis-open.orgへ送られたい。

この規定についての既知の誤りは,http://www.oasis-open.org/committees/relax-ng/spec-20011203-errata.htmlに掲載してある。

注意

2003年7月19日時点での正誤表は、この日本語訳にはすべて反映されている。

目次

1. はじめに
2. データモデル
2.1.
3. 完全な構文
3.1.
4. 単純化
4.1. 注釈
4.2. 空白
4.3. datatypeLibrary属性
4.4. value要素のtype属性
4.5. href 属性
4.6. externalRef 要素
4.7. include 要素
4.8. elementとattribute要素のname 属性
4.9. ns 属性
4.10. QName
4.11. div 要素
4.12. 子要素の数
4.13. mixed 要素
4.14. optional 要素
4.15. zeroOrMore 要素
4.16. 制約
4.17. combine 属性
4.18. grammar 要素
4.19. define及びref 要素
4.20. notAllowed 要素
4.21. empty 要素
5. 単純な構文
5.1.
6. 意味
6.1. 名前クラス
6.2. パターン
6.2.1. choiceパターン
6.2.2. groupパターン
6.2.3. emptyパターン
6.2.4. textパターン
6.2.5. oneOrMoreパターン
6.2.6. interleaveパターン
6.2.7. element及びattributeパターン
6.2.8. data及びvalueパターン
6.2.9. 組み込みデータ型ライブラリ
6.2.10. listパターン
6.3. 妥当性
6.4.
7. 制限
7.1. 文脈上の制限
7.1.1. attributeパターン
7.1.2. oneOrMoreパターン
7.1.3. listパターン
7.1.4. data中のexceptパターン
7.1.5. start要素
7.2. 文字列の並び
7.3. 属性の制限
7.4. interleave の制限
8. 適合性

附属書

A. RELAX NGのためのRELAX NGスキーマ
B. 版0.9からの差分
C. RELAX NG TC (参考)
文献

1. はじめに

この規格は,次を規定する。

  • XML文書が正しいRELAX NGスキーマになるのはどんな場合か

  • 正しいRELAX NGスキーマに照らして、XML文書が妥当になるのはどんな場合か

正しいRELAX NGスキーマに照らして妥当性検証されるXML文書を,インスタンスと呼ぶ。

この規格の構成を次に示す。項2は,データモデルを示し,この規格の以降の部分で用 いるXML文書の抽象化を示す。項3は,RELAX NGス キーマの構文を示す。どんな正しいRELAX NGスキーマも,この構文に 適合しなければならない。項4は,RELAX NGス キーマを単純化するために適用される変換の並びを示す。これらの変換には, 正しいRELAX NGスキーマが満たさなければならないある制限をチェッ クすることも含む。項5は,変換を適用した結 果の構文を示す。この単純な構文は,完全な構文の部分集合である。項6は,単純な構文を用いた正しいRELAX NGスキーマの意 味を示す。ここで意味とは,要素がRELAX NGスキーマに照らして妥当になるのは どんなときかの規定である。項7は,単純な構文を用いて制限事項を示す。単純な形式への変換の後に、正しいRELAX NGスキーマはこれらの制限事項を満たさなければならない。最後に項8は,RELAX NGの妥当性検証器に関する適合性要件を示す。

この規格とは別の入門書が用意されている。([Tutorial]を参照されたい。)

2. データモデル

RELAX NGでは,スキーマとインスタンスのどちらを表現す るXML文書も抽象データモデルによって扱う。スキーマやインスタンスを表 現するXML文書は,[XML 1.0]に適合する整形式でなければな らず,[XML Namespaces]の制約に適合しなければならない。

XML文書は,要素によって表現される。要素は,次のものから成る。

  • 名前

  • 文脈

  • 属性の集合

  • 0個以上の子の順序付き並び (どの子も,要素又は空でない文字列のどちらかとし,並びの中に二つの文字列が続いて現れてはならない。)

名前は,次のものから成る。

  • 名前空間URIを表す文字列 (空文字列は特別な意味をもち,名前空間がないことを表す。)

  • 局所名を表す文字列 (この文字列は,[XML Namespaces]のNCName生成規則とマッチする。)

文脈は,次のものから成る。

  • 基底URI

  • 名前空間マップ。これは,接頭辞を名前空間URIに対応付ける。また,デフォルト名前空間URI(xmlns属性によって宣言されるもの。)を指定してもよい。

属性は,次のものから成る。

  • 名前

  • 値を表す文字列

文字列は,0個以上の文字の並びから成り,文字は[XML 1.0]において定義される。

XML文書のための要素は,次に示すとおりに[XML Infoset]のインスタンスから構成される。情報項目の x特性の値を参照するために,記法 [x]を用いる。要素を文書情報項目から構成するには,[document element]から要素を構成する。要素を 要素情報項目から構成するには,名前 を[namespace name]及び[local name]から構成し,文脈を[base URI]及び [in-scope namespaces]から構成し,属性(複数)を[attributes]から構成し,子(複数)を [children]から構成する。要素の属性(複数)を属性情報項目の順 序なし集合から構成するには, 各属性情報項目から属性を構成することを繰り返す。要素の子(複数)を 子情報項目のリストから構成するには, まず要素情報項目及び文字情報項 目以外の情報項目を削除し,次に リスト中の各要素情報項目から要素を構築し, 連続する文字情報項目をできるだけ繋げることによって文字列を構成する。 属性を属 性情報項目から構成するには,名前を[namespace name]及び [local name]から構成し,値を[normalized value]から構成する。 要素及び属性の名前を[namespace name]及び[local name]から構成するとき,[namespace name]特性が存在しなければ,空 の文字列及び[local name]から構成する。文字列を文字情報項目の並びから 構成するには,各文字情報項目の [character code]から文字を構成することを繰り返す。

単一のXML文書について複数の異なる情報集合があり得る。これは,すべてのDTD宣言を処理し,すべての外部解析対象実体を展開することがXMLパーサに義務付けられていないことによる。これらの複数の情報集合の中には,[all declarations processed]が真であり,未拡張実体参照情報項目を全く含まない情報集合が正確に一つだけ存在する。この情報集合を,RELAX NGデータモデルを定義するための基本とする。

2.1. 例

文書http://www.example.com/doc.xmlが,次に示すものとする。

<?xml version="1.0"?>
<foo><pre1:bar1 xmlns:pre1="http://www.example.com/n1"/><pre2:bar2
  xmlns:pre2="http://www.example.com/n2"/></foo>

この文書を表す要素は,次のものをもつ。

  • 名前 (これは,次のものをもつ。)

    • 名前空間URIとしての空文字列 (名前空間がないことを表す。)

    • 局所名としてのfoo

  • 文脈 (これは,次のものをもつ。)

    • 基底URIとしてhttp://www.example.com/doc.xml

    • 名前空間マップ (これは,次のとおりとする。)

      • 接頭辞xmlを名前空間URI http://www.w3.org/XML/1998/namespaceにマップする。(xml接頭辞は,すべてのXML文書において暗黙的に宣言される。)

      • デフォルトの名前空間URIとして空文字列を指定する。

  • 属性の空集合

  • 次のものをもつ要素から成る子どもの並び

    • 名前 (これは,次のものをもつ。)

      • 名前空間URIとしての http://www.example.com/n1

      • 局所名としてbar1

    • 文脈 (これは,次のものをもつ。)

      • 基底URIとしての http://www.example.com/doc.xml

      • 名前空間マップ (これは,次のとおりとする。)

        • 接頭辞pre1を名前空間URI http://www.example.com/n1にマップする

        • 接頭辞xmlを名前空間URI http://www.w3.org/XML/1998/namespaceにマップする。

        • デフォルトの名前空間URIとして空文字列を指定する。

    • 属性の空集合

    • 子どもの空の並び

    これらには,次のものをもつ要素が続く。

    • 名前 (これは,次のものをもつ。)

      • 名前空間URIとしての http://www.example.com/n2

      • 局所名としてのbar2

    • 文脈 (これは,次のものをもつ。)

      • 基底URIとしての http://www.example.com/doc.xml

      • 名前空間マップ (これは,次のとおりとする。)

        • 接頭辞pre2を名前空間URI http://www.example.com/n2にマップする。

        • 接頭辞xmlを名前空間URI http://www.w3.org/XML/1998/namespaceにマップする。

        • デフォルトの名前空間URIとして空文字列を指定する。

    • 属性の空集合

    • 子(複数)の空の列

3. 完全な構文

次の文法は,RELAX NGの構文を要約する。ここでの記法は, RELAX NGスキーマをXMLで表現したものを,文字の並びとして扱う。しかし、 文法はデータモデルレベルのものであることを理解しなければならない。例え ば,ここでの構文は<text/>を使用している が,インスタンス又はスキーマでは <text></text>を代わりに使用できる。これは,デー タモデルレベルでは,どちらも同じ要素を表すことによる。この文法に示され るすべての要素は,次に示す名前空間URIで修飾される。

http://relaxng.org/ns/structure/1.0

記号QName及びNCNameは,[XML Namespaces]に おいて定義される。anyURI記号は,[W3C XML Schema Datatypes]のanyURI データ型と同じ意味をもつ。すなわち,文字列であって,許可されない値を [XLink]の5.4 に示されるとおりに別扱いすると,[RFC 2396](これは[RFC 2732]によって修正されて いる。)に定義されるURI参照になるものを示す。記号stringは,どんな文字 列ともマッチする。

明示的に示される属性に加えて,どの要素も ns属性をもつことができ,どの要素も datatypeLibrary属性をもつことができる。 ns属性は,どんな値をももつことができる。 datatypeLibrary属性の値は,前の段落に示されるanyURI 記号とマッチしなければならない。さらに,URI参照の相対形式を用いてはな らず,素片識別子をもってはならない。例外として,この属性の値は 空文字列であってもよい。

どの要素も,文法に示される属性に加えて,外来の属性を もつこともできる。外来の属性とは,空文字列でもRELAX NG名前空間URIでも ない名前空間URIの名前をもつ属性とする。文字列である子をもつことが できないどの要素も(つまり,valueparam及びname以外のどの要素も), 文法に示される子要素に加えて,外来の子要素をもってもよい。外来の要素は, RELAX NG名前空間URIでない名前空間URIの名前をもつ要素とする。他の子要素 と外来の子要素の間の相対的な位置についての制約はない。

どの要素も,子として,完全に空白文字のみから成る文字 列をもつことができる。ここで空白文字は,#x20,#x9,#xD又は#xAの一つと する。空白文字列である子と子要素の間の相対的な位置についての制約はない。

nametype及びcombineの各属性の値,並びに各name要素の内容は、 先頭及び末尾に空白をもってもよい。

pattern  ::=  <element name="QName"> pattern+ </element>
| <element> nameClass pattern+ </element>
| <attribute name="QName"> [pattern] </attribute>
| <attribute> nameClass [pattern] </attribute>
| <group> pattern+ </group>
| <interleave> pattern+ </interleave>
| <choice> pattern+ </choice>
| <optional> pattern+ </optional>
| <zeroOrMore> pattern+ </zeroOrMore>
| <oneOrMore> pattern+ </oneOrMore>
| <list> pattern+ </list>
| <mixed> pattern+ </mixed>
| <ref name="NCName"/>
| <parentRef name="NCName"/>
| <empty/>
| <text/>
| <value [type="NCName"]> string </value>
| <data type="NCName"> param* [exceptPattern] </data>
| <notAllowed/>
| <externalRef href="anyURI"/>
| <grammar> grammarContent* </grammar>
param  ::=  <param name="NCName"> string </param>
exceptPattern  ::=  <except> pattern+ </except>
grammarContent  ::=  start
| define
| <div> grammarContent* </div>
| <include href="anyURI"> includeContent* </include>
includeContent  ::=  start
| define
| <div> includeContent* </div>
start  ::=  <start [combine="method"]> pattern </start>
define  ::=  <define name="NCName" [combine="method"]> pattern+ </define>
method  ::=  choice
| interleave
nameClass  ::=  <name> QName </name>
| <anyName> [exceptNameClass] </anyName>
| <nsName> [exceptNameClass] </nsName>
| <choice> nameClass+ </choice>
exceptNameClass  ::=  <except> nameClass+ </except>

3.1. 例

項2.1の文書のための スキーマ例を完全な構文で示す。

<?xml version="1.0"?>
<element name="foo"
         xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:a="http://relaxng.org/ns/annotation/1.0"
         xmlns:ex1="http://www.example.com/n1"
         xmlns:ex2="http://www.example.com/n2">
  <a:documentation>A foo element.</a:documentation>
  <element name="ex1:bar1">
    <empty/>
  </element>
  <element name="ex2:bar2">
    <empty/>
  </element>
</element>

4. 単純化

前の節で与えられた完全な構文は、以下の変換規則を順番とおりに適用することで、より単純な構文に変換する。それぞれの規則は、次の規則が適用される前に、スキーマ内の全ての要素に適用されたかのような効果をもたらさねばならない。個々の変換規則は、正しいスキーマが満たすべき制約を指定している場合がある。変換規則はデータモデルのレベルで適用する。スキーマを解析し、データモデルのインスタンスを構築した後に変換を適用する。

4.1. 注釈

外来の属性および要素は取り除かれる。

注意

この段階でxml:baseを取り除くこと は安全である。なぜなら,xml:base属性は要素情報項目 の[base URI]を確定するために用いられ、さらに[base URI]から要素の文脈 の基底URIが作られている。したがって、文書がデータモデルのインスタンスに解 析後にxml:base属性を処分することができる。

4.2. 空白

value及びparamを除くどの要素についても、空白文字のみからなる文字列である子を取り除く。

name, typeおよび combine 属性の値と、name要素の内容において、先頭および末尾の空白文字を取り除く。

4.3. datatypeLibrary属性

datatypeLibary属性の値 は、[XLink]の5.4節で指定されるとおりに、許容されない文字 を別扱いすることによって変換する。

datatypeLibrary属性をもたないどのdata又はvalue要素にも、datatypeLibrary属性を追加する。追加されるdatatypeLibrary属性の値は、datatypeLibrary属性をもつもっとも近い祖先要素のdatatypeLibrary属性の値とする。そのような祖先が存在しない場合は空文字列とする。つぎに、datatypeLibrary属性であって、dataまたはvalue以外の要素に付属するものを取り除く。

4.4. value要素のtype属性

type属性を持たないvalue要素には, 値がtokenであるtype属性を付け加え,datatypeLibrary属性の値を空文字列に置き換える。

4.5. href 属性

externalRefまたはinclude要素のhref属性の値は、まず[XLink]の5.4節で指定されるとおりに、許されない文字を別扱いすることによって変換する。次に,URI参照を[RFC 2396]の5.2に記述された絶対形式に帰着させる。これは、href属性を持つ要素の文脈から得られる基底URIを用いて行う。

href属性の値は(項2で示されたとおりに)要素を構築するために使用する。これは、以下のように行われねばならない。URI参照は、URIそのものと素片識別子からなる(素片識別子は省いてもよい)。まずURIによって特定される資源を取り出す。その結果はMIMEエンティティであり、MIMEメディア型がラベルとして付されたバイト列になる。MIMEエンティティと素片識別子(なくてもよい)から要素がどのように構築されるかは、メディア型によって定まる。メディア型が、application/xmlまたはtext/xmlであるとき、関連するRFC(執筆時点では[RFC 3023])に従って、MIMEエンティティはXML文書として解析され ねばならない。そして、解析結果から,項2で指定 されたように、要素を構築しなければならない。特に、 charsetパラメタはこのRFCで指定されたとおりに扱われねばな らない。この仕様書は、application/xmltext/xmlを除き、メディア型の取り扱いを定義しない。 href属性は、素片識別子を含んではならない。ただし、 その属性によって特定される資源のもつメディア型の登録が、そのメディア型 のための素片識別子の解釈のしかたを定義している場合は、含んでもよい。

注意

[RFC 3023] はapplication/xmlまたはtext/xmlの素片識別子の解釈を定義しない。

4.6. externalRef 要素

externalRef要素は、以下のとおりに変換する。 項4.5で指定されたとおりに,href属性の値であるURI参照を用いて要素を構築する。 この要素は、パターンの構文にマッチしなければならない。 この要素を、この節で与えた規則及び本章の以前の節で与えた規則を適用して再帰的に変換する。この変換は、繰り返しに陥ってはならない。 言い換えれば、参照された要素を変換するとき、 同じ値のhref属性をもつexternalRef要素の参照が起こってはならない。

参照された要素がns属性を持たないなら、 externalRef要素のns属性を、参 照された要素に転記する。そして、externalRef要素を、 参照された要素と置き換える。

4.7. include 要素

includeは以下のとおりに変換する。項4.5で指定されたとおりに、href属性の値 をURI参照として用いて要素を構築する。この要素は、文法の構文にマッチす るgrammar要素でなければならない。

このgrammar要素は、本節で与えた規則及び本章の以前の節で与えた規則を適用して再帰的に変換する。 この変換は、繰り返しに陥ってはならない。 言い換えれば、grammar要素を変換するとき、 同じ値のhref属性をもつinclude要素の参照が起こってはならない。

ある要素の構成部品とは、その要素のすべての子(複数)及び すべてのdiv子要素の構成部品であると定義する。 include要素がstart構成部品をもつなら、grammar要素はstart構成部品を持たねばならない。 include要素がstart構成部品をもつなら、すべてのstartgrammar要素から取り除く。 include要素がdefine構成部品をもつなら、grammar要素は同じ名前のdefine構成部品を持たねばならない。 include要素のどのdefine構成部品についても、同じ名前のすべてのdefine構成部品をgrammar要素から取り除く。

include要素をdiv要素に変換する。まず、 divの属性は、href属性を除き、includeの属性とする。 div要素の子(複数)は、(直前の段落で述べたとおりにstartdefine構成部品を取り除いた後の)grammar要素であり、その後にinclude要素の子(複数)が続く。次に,grammar要素をdiv要素に変換する。

4.8. elementattribute要素のname 属性

elementまたはattribute要素のname属性はname子要素に変換する。

もしattribute要素がname属性を持ちns属性を持たないなら、ns=""属性をname子要素に追加する。

4.9. ns 属性

ns属性を持たないname, nsNameまたはvalue要素には、ns要素を追加する。追加されるns属性の値は、ns属性をもつもっとも近い祖先要素のns属性の値とする。そのような祖先要素が存在しない場合は空文字列とする。次に、ns属性であって、name, nsNameまたはvalue以外の要素にあるものを取り除く。

注意

ns属性の値には、 許されない文字を別扱いする変換又は他のいかなる変換も適用しない。なぜなら、インスタンス中の名前空間URIにはどのような変換も適用されておらず、ns属性の値はこの名前空間URIと比較されるからである。

注意

includeexternalRef要素が解決されるのは、datatypeLibrary属性が追加された後で、nsが追加される前なので、ns属性は外部スキーマにも継承されるが、datatypeLibrary属性はそうではない。

4.10. QName

接頭辞をもつどのname要素についても、接頭辞を取り除き、ns属性を追加する。既存のns属性があっても置き換える。追加するns属性の値は、name要素の文脈での名前空間マップによってこの接頭辞がマップされるものとする。文脈は、この接頭辞についてのマップを持たなければならない。

4.11. div 要素

div要素は、その子(複数)によって置き換える。

4.12. 子要素の数

define, oneOrMore, zeroOrMore, optional, list または mixed要素は、正確に1つの子要素をもつように変換する。 それが1つより多くの子要素をもつなら、それらをgroup要素によってまとめる。 同様に、element要素は正確に2つの子要素をもつように変換する。最初のものは名前クラスで、2番目のものはパターンである。 2つより多くの子要素をもつなら、最初の要素以外の子要素をgroup要素でまとめる。

except要素は正確に1つの子要素をもつように変換する。 1つより多くの子要素をもつなら、子要素をchoice要素でまとめる。

attribute要素がたった1つの子要素(名前クラス)をもつなら、text要素を追加する。

choice, groupまたは interleave要素は正確に2つの子要素をもつように変換する。 1つの子要素をもつなら、この子要素によって置き換える。2つより多くの子要素をもつなら、親要素と同じ名前の新しい要素によって最初の2つの子要素をまとめる。たとえば、

<choice> p1 p2 p3 </choice>

は以下のように変換する。

<choice> <choice> p1 p2 </choice> p3 </choice>

この操作は子要素の数を1つ減らす。子要素の数が正確に2つになるまで、この変換を繰り返し適用する。

4.13. mixed 要素

mixed要素はtext要素を伴うインタリーブに変換する。

<mixed> p </mixed>

は以下のように変換する。

<interleave> p <text/> </interleave>

4.14. optional 要素

optional要素は、choice要素に変換する。このchoice要素の片方の子は,optional要素の子とし,もう一方の子はemptyとする。

<optional> p </optional>

は以下のとおりに変換する。

<choice> p <empty/> </choice>

4.15. zeroOrMore 要素

zeroOrMore要素は choice要素に変換する。この choice要素の片方の子は, <oneOrMore> p </oneOrMore>要素であり,もう一方の子はempty要素とする。ここで pzeroOrMore要素の子とする。

<zeroOrMore> p </zeroOrMore>

は以下のとおりに変換する。

<choice> <oneOrMore> p </oneOrMore> <empty/> </choice>

4.16. 制約

この規則は、変換は行わないが、様々な制約をチェックする。

注意

この節の制約は、項7で規定される制約と異なり、 いかなるref要素も解決することなしにチェックすることができる。そのため、これらの制約は,到達可能ではない(項4.19参照)という理由またはnotAllowed(項4.20参照)が原因でこのあとの段階の単純化の間には現れないパターンにも適用される。

anyName要素の子要素であるexcept要素は、 anyName子孫要素をもってはならない。 nsName要素の子要素であるexcept要素は、 nsNameまたはanyName子孫要素をもってはならない。

attribute要素の最初の子またはattributeの最初の子の子孫として出現し、ns要素が空文字列と等しいname要素は、xmlnsと等しい内容を持ってはならない。

attribute要素の最初の子またはattributeの最初の子の子孫として出現するnameまたはnsName要素は、http://www.w3.org/2000/xmlnsという値のns属性を持ってはならない。

注意

[XML Infoset]は 名前空間宣言属性の名前空間URIがhttp://www.w3.org/2000/xmlnsであるべきことを定義している。

dataまたはvalue要素は、 データ型を正しく使用しなければならない。 特に、type属性は、 datatypeLibrary属性の値で識別されるデータ型ライブラリに含まれるデータ型を特定しなければならない。 data要素において、パラメタリストはデータ型(項6.2.8参照)で許されるものの1つでなければならない。

4.17. combine 属性

個々のgrammar要素において、同じ名前をもつすべてのdefine要素はそれぞれ結合される。 どの名前についても、その名前をもつdefine要素であってcombine属性を持たないものが1つより多く存在してはならない。 どの名前に対しても、その名前をもつdefine要素であってcombine属性の値がchoiceなものがあれば、その名前をもつdefine要素であってcombine属性の値がinterleaveなものがあってはならなない。 したがって、どの名前についても、 その名前をもつdefine要素が1つより多く存在するなら、その名前に対するcombine属性の値は一意に定まる。 この一意な値を確認した後で、combine属性は取り除かれる。 以下の二つの定義

<define name="n">
  p1
</define>
<define name="n">
  p2
</define>

は以下のとおりに結合される。

<define name="n">
  <c>
    p1
    p2
  </c>
</define>

ここでccombine属性の値である。 個々の名前に対して正確に1つのdefine要素になるまで、define要素の対を結合することを繰り返す。

同様に、個々のgrammar要素は、すべてのstart要素を互いに結合する。 combine属性を持たないstart要素が1つより多く存在してはならない。 もし、choiceという値のcombine属性をもつstart要素が存在するなら、 interleaveという値のcombine属性をもつstart要素が存在してはならない。

4.18. grammar 要素

この規則によって、スキーマはそのトップレベル要素がgrammarであり、それ以外のgrammar要素は存在しないように変換される。

ある要素の直上の文法とは、最も近い祖先の grammar要素であると定義する。 ref要素がdefine要素を 参照するのは、それらのname属 性の値が同じで、それらの直上の文法が同じときである。 parentRef要素がdefine要素を 参照するのは、そ れらのname属性の値が同じであり、 parentRef要素の直上の文法の直上の文法が、 define要素の直上の文法と同じときである。 どのref または parentRef要素も、 define要素を参照しなければならない。 grammar要素は一つのstart子要素をもたなければならない。

最初に、トップレベルのパターンpを、<grammar><start>p</start></grammar>に置き換える。次に、define要素の名前を、 スキーマ内のいずれの2つのdefineも同じ名前を持たないように変える。define要素の名前を変更するには、name属性の値を変更し、そのdefine要素を参照するすべてのref及びparentRef要素のname属性の値を変更する。次に、すべてのdefine要素をトップレベルのgrammar要素の子になるように移動させる。ネストした個々のgrammar要素をそのstart要素の子で置き換え、個々のparentRef要素をref要素に名前を変更する。

4.19. define及びref 要素

この規則では、文法は element要素はいずれも define要素の子となり、 define要素の子はいずれもelement要素となるように変換される。

最初に、到達可能ではないdefine要素を取り除く。 define要素は、到達可能なref要素に参照されているときに到達可能である。 ref要素は、start要素または到達可能なdefine要素の子孫であるとき、到達可能である。 いま、define要素の子ではない個々のelement要素について、grammar elementにdefine要素を追加する。 そして、element要素をref要素で置き換え、追加したdefineを参照する。 追加されるdefine要素のname属性の値は、 他のいかなるdefine要素のもつname属性の値とも異なっていなければならない。 追加されるdefine要素の子要素は、element要素である。

ref要素が展開可能なのは、そ の参照するdefine要素が、element 要素を子としてもたないときと定義する。 展開可能なref要素であって、 start要素又はelement要素の子孫である ものは展開する。展開をするには、 参照されているdefine要素の子要素でref要素を置き換え、この置き換え後に含まれる展開可能なref要素を再帰的に展開する。 この結果ループが発生してはならない。 言い換えれば、 nという値のnameをもつref要素の置き換えを展開するときに、 再びnという値のnameをもつref要素の展開を必要としてはならない。 最後に、子がelement要素ではないすべてのdefine要素を取り除く。

4.20. notAllowed 要素

この規則では、文法はnotAllowed要素がstart又はelement要素の子要素としてしか出現しないように変換する。 notAllowed子要素をもつattribute, list, group, interleave, または oneOrMore要素は、notAllowedに変換する。 2つのnotAllowed子要素をもつchoice要素は、 1つのnotAllowed要素に変換する。 1つのnotAllowed子要素をもつchoice要素の子要素は、もう一方の子要素に変換する。 notAllowed子要素をもつexcept要素は、取り除く。 これらの変換は、適用できなくなるまで繰り返し適用する。 到達可能ではないdefine要素は取り除く。

4.21. empty 要素

この規則では、文法は empty要素が group, interleave, または oneOrMore要素の子要素 またはchoice要素の2番目の子要素 に出現しないように 変換する。 2つのempty子要素を group, interleave又はchoice要素は 1つのempty要素に変換する。 1つのempty子要素をもつ group 又はinterleave要素は、もう一方の子要素に変換する。 2番目の子要素がempty要素であるchoice要素は2つの子要素を交換することによって変換する。 empty子要素をもつoneOrMore要素はempty要素に変換される。 これらの変換は、適用できなくなるまで繰り返し適用する。

5. 単純な構文

項4にあるすべての規則を適用すれば、 スキーマは次の文法にマッチすることになる。

grammar  ::=  <grammar> <start> top </start> define* </grammar>
define  ::=  <define name="NCName"> <element> nameClass top </element> </define>
top  ::=  <notAllowed/>
| pattern
pattern  ::=  <empty/>
| nonEmptyPattern
nonEmptyPattern  ::=  <text/>
| <data type="NCName" datatypeLibrary="anyURI"> param* [exceptPattern] </data>
| <value datatypeLibrary="anyURI" type="NCName" ns="string"> string </value>
| <list> pattern </list>
| <attribute> nameClass pattern </attribute>
| <ref name="NCName"/>
| <oneOrMore> nonEmptyPattern </oneOrMore>
| <choice> pattern nonEmptyPattern </choice>
| <group> nonEmptyPattern nonEmptyPattern </group>
| <interleave> nonEmptyPattern nonEmptyPattern </interleave>
param  ::=  <param name="NCName"> string </param>
exceptPattern  ::=  <except> pattern </except>
nameClass  ::=  <anyName> [exceptNameClass] </anyName>
| <nsName ns="string"> [exceptNameClass] </nsName>
| <name ns="string"> NCName </name>
| <choice> nameClass nameClass </choice>
exceptNameClass  ::=  <except> nameClass </except>

この文法では、明示的に許容されていない要素や属性は許容されない。

5.1. 例

次の例は、 項3.1にあるスキーマが単純な構文に どう変換されるかを示す。

<?xml version="1.0"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
  <start>
    <ref name="foo.element"/>
  </start>

  <define name="foo.element">
    <element>
      <name ns="">foo</name>
      <group>
        <ref name="bar1.element"/>
        <ref name="bar2.element"/>
      </group>
    </element>
  </define>

  <define name="bar1.element">
    <element>
      <name ns="http://www.example.com/n1">bar1</name>
      <empty/>
    </element>
  </define>

  <define name="bar2.element">
    <element>
      <name ns="http://www.example.com/n2">bar2</name>
      <empty/>
    </element>
  </define>
</grammar>

注意

厳密に言えば,単純化の結果はデータモデルに従う インスタンスであってXML文書ではない。簡便さのため、データモデルに 従うインスタンスをXML文書によって表現する。

6. 意味

この章では、単純な構文に変換された正しいRELAX NGスキーマ の意味を定義する。RELAX NGスキーマの意味は,そのスキーマに照らして 妥当なXML文書がなんであるかという指定である。意味は形式的に記述する。 形式化には,公理と推論規則を用いる。公理は,無条件に証明可能な命題 である。推論規則は,ひとつ以上の前提条件をもち、正確に一つの結論をもつ。 前提条件は,肯定的又は否定的である。推論規則の肯定的な前提条件のすべてが 証明可能で、否定的な推論規則のいずれも証明可能ではないとき、推論の結論 は証明可能である。XML文書がRELAX NGスキーマに照らして妥当であるのは、 それが妥当であるという命題が本章で示す形式化において証明可能 なときである。

注意

ここで用いた形式化は証明システムに 類似する。しかし、伝統的な証明システムは肯定的な 前提条件しか持たない。

推論規則のための記法は、前提条件と結論を水平線で分け る。前提条件は線の上に、結論は線の下に示す。前提条件が not(p) の形をしている場合は,否定的な前提条 件である。そうでなければ、肯定的な前提条件である。公理も推論規則も変数 を用いることができる。変数は名前をもち、さらに添え字をもつこともある。 変数の名前はイタリッ クで示す。変数の名前から、その変数がとりうる値が決まる。公理と推論規則 には,それが含む変数についての全称記号が暗黙に適用される。これについて は、次に詳しく説明する。

一つの推論規則又は公理において、ある変数が1回以上出 現することがありうるので、変数がとりうるオブジェクトごとに同値関係を定 義する必要がある。どの種類のオブジェクトについても、同値関係は値に基づ いて決まる。ある種類の二つのオブジェクトが同値であるのは、それらの構成 物が同値であるときである。例えば,二つの属性が同じとみなすのは、それ らの名前も値も同じときである。二つの文字が同値であるのは、そのUnicode 文字コードが同じときである。

6.1. 名前クラス

名前クラスについて主要な意味概念は、名前が名前クラス に属することである。名前クラスは、生成規則nameClassにマッチする要素 である。名前は,項2で定義されている。 名前は、名前空間URIと局所名から成る。

次に示す記法を用いる。

n

名前を値とする変数

nc

名前クラスを値とする変数

n in nc

nが名前クラスncに属することを 意味する

最初の公理、"anyName 1"を次に示す。

(anyName 1)
n in <anyName/>

この公理は,どんな名前nについて も,nは名前クラス<anyName/>に属す ることを定める。この公理に現れる変数には、全称記号が暗黙に指定されてい ることに注意。この暗黙の指定があるため、この公理はどんな名前nについても適用できる。

最初の推論規則も同程度に簡単である。

(anyName 2)
not(n in nc)

n in <anyName> <except> nc </except> </anyName>

この推論規則は,どんな名前n及び 名前クラスncに対しても, もしnncに属さないのなら, n<anyName> <except> nc </except> </anyName>に属する ことを示す。言い換えれば, <anyName> <except> nc </except> </anyName>ncにマッチしないどんな名前にもマッチする。

次に示す補助的な記法が必要になる。

ln

局所名を値とする変数。局所名は文字列であり、 [XML Namespaces]のNCName生成規則にマッチするもの (すなわちコロンを含まない名前)である。

u

URIを値とする変数

name( u, ln )

URIu と局所名lnをもつ名前を構築する

名前クラスについての他の公理及び推論規則を次に示す。

(nsName 1)
name( u, ln ) in <nsName ns="u"/>
(nsName 2)
not(name( u, ln ) in nc)

name( u, ln ) in <nsName ns="u"> <except> nc </except> </nsName>
(name)
name( u, ln ) in <name ns="u"> ln </name>
(name choice 1)
n in nc1

n in <choice> nc1 nc2 </choice>
(name choice 2)
n in nc2

n in <choice> nc1 nc2 </choice>

6.2. パターン

パターンのための公理と推論規則では、次の記法 を用いる。

cx

文脈(項2で定義したもの)を値とする変数

a

属性の集合を値とする変数。 一つの属性しか含まない集合は,その属性と同一視する。

m

要素及び文字列からなる列を値とする変数。一つの要素又は文字列しか含ま ない列は,その要素又は文字列と同一視する。mの値で ある列は、文字列が連続したものを含んでもよく,空の文字列を含んでもよい。 したがって、mの値である列であって、要素の子(複数)とし ては出現できないものがある。

p

パターン(パターン生成規則にマッチする要素)を 値とする変数

cx |- a; m =~ p

文脈cxにおいて、属性(複数)a並びに 要素及び文字列からなる列mがパターン pにマッチすることを意味する。

6.2.1. choiceパターン

choiceパターンの意味を次のとおりに 定める。

(choice 1)
cx |- a; m =~ p1

cx |- a; m =~ <choice> p1 p2 </choice>
(choice 2)
cx |- a; m =~ p2

cx |- a; m =~ <choice> p1 p2 </choice>

6.2.2. groupパターン

次に示す補助的な記法を用いる。

m1, m2

m1と列m2を連結したものを表す。

a1 + a2

a1a2の和集合を表す。

groupパターンの意味を次のとおりに 定める。

(group)
cx |- a1; m1 =~ p1    cx |- a2; m2 =~ p2

cx |- a1 + a2; m1, m2 =~ <group> p1 p2 </group>

注意

項7.3に 示す制限は、推論規則の結論において構築される属性集合に、同一の名前をもつ 複数の属性がないことを保証する。

6.2.3. emptyパターン

次に示す補助的な記法を用いる。

( )

空の列を表す。

{ }

空の集合を表す。

emptyパターンの意味を次のとおりに 定める。

(empty)
cx |- { }; ( ) =~ <empty/>

6.2.4. textパターン

次に示す補助的な記法を用いる。

s

文字列を値とする変数

textパターンの意味を次のとおりに 定める。

(text 1)
cx |- { }; ( ) =~ <text/>
(text 2)
cx |- { }; m =~ <text/>

cx |- { }; m, s =~ <text/>

この規則は,text は0個以上の文字列にマッチすることを意味している。

6.2.5. oneOrMoreパターン

次に示す補助的な記法を用いる。

disjoint(a1, a2)

a1にある属性の名前であって,しかも a2にある属性の名前であるものは 存在しないことを意味している。

oneOrMoreパターンの意味を次のとおりに 定める。

(oneOrMore 1)
cx |- a; m =~ p

cx |- a; m =~ <oneOrMore> p </oneOrMore>
(oneOrMore 2)
cx |- a1; m1 =~ p    cx |- a2; m2 =~ <oneOrMore> p </oneOrMore>    disjoint(a1, a2)

cx |- a1 + a2; m1, m2 =~ <oneOrMore> p </oneOrMore>

6.2.6. interleaveパターン

次に示す補助的な記法を用いる。

m1 interleaves m2; m3

m1は、 m2 及びm3のインタリーブ であることを示す。

インタリーブの意味を次の推論規則によって定める。

(interleaves 1)
( ) interleaves ( ); ( )
(interleaves 2)
m1 interleaves m2; m3

m4, m1 interleaves m4, m2; m3
(interleaves 3)
m1 interleaves m2; m3

m4, m1 interleaves m2; m4, m3

例えば, <a/><a/><b/> のインタリーブは <a/><a/><b/><a/><b/><a/>及び <b/><a/><a/> である。

interleaveパターンの意味を次のとおりに 定める。

(interleave)
cx |- a1; m1 =~ p1    cx |- a2; m2 =~ p2    m3 interleaves m1; m2

cx |- a1 + a2; m3 =~ <interleave> p1 p2 </interleave>

注意

項7.3にある制限は, 推論規則の結論において構築される属性集合は、同一の名前をもつ複数の属性を もたないことを保証する。

6.2.7. element及びattributeパターン

属性の値は,常に単一の文字列である。文字列が空であっ てもよい。したがって、空の列は属性の値とはなり得ない。一方,要素の子(複数) は空の列であってもよいが、空の文字列であることはない。検証が要素と 属性を統一的に扱うことを保証するため,マッチの変種として 弱いマッチを導入する。弱いマッチ は、 属性の値をパターンにマッチさせるとき、属性(複数)並びに要素の子(複数)を パターンにマッチさせるときに用いる。弱いマッチを定義するために,次の 記法を用いる。

""

空の文字列を表す。

ws

空列を値とする、又は 空白のみから構成される文字列を値とする変数

cx |- a; m =~weak p

文脈cxにおいて、属性a並びに要素及び文字からなる列mとが、パター ンpと弱いマッチをすることを意味する。

弱いマッチの意味を次のとおりに定める。

(weak match 1)
cx |- a; m =~ p

cx |- a; m =~weak p
(weak match 2)
cx |- a; ( ) =~ p

cx |- a; ws =~weak p
(weak match 3)
cx |- a; "" =~ p

cx |- a; ( ) =~weak p

次に示す補助的な記法を用いる。

attribute( n, s )

名前nと値sをもつ属性を構築する。

element( n, cx, a, m )

名前がnで、文脈がcxで、 属性(複数)がaで、子(複数)が 混在列mである要素を構築する。

okAsChildren(m)

混在列mが、要素の子(複数)として 出現できるものであることを示す。すなわち、空の文字列が現れることはなく,二つの文字列が連続として現れるこ ともない。

deref(ln) = <element> nc p </element>

文法が <define name="ln"> <element> nc p </element> </define>を含むことを意味する。

attributeパターンの意味を次のとおりに 定める。

(attribute)
cx |- { }; s =~weak p    n in nc

cx |- attribute( n, s ); ( ) =~ <attribute> nc p </attribute>

elementパターンの意味を次のとおりに 定める。

(element)
cx1 |- a; m =~weak p    n in nc    okAsChildren(m)    deref(ln) = <element> nc p </element>

cx2 |- { }; ws1, element( n, cx1, a, m ), ws2 =~ <ref name="ln"/>

6.2.8. data及びvalueパターン

RELAX NGは、データ型についてはデータ型ライブラリに委 ねている。データ型ライブラリはURIによって特定する。あるデータ型ラ イブラリに属するデータ型はNCNameによって特定する。データ型ライブラリ は二つの機能をもつ。

  • ある文字列が、あるデータ型において許される表現である かどうかを決定することができる。この機能は,0個以上のパラメタからな るリストを受け取る。例えば,文字列データ型は、文字列の長さを指定するパ ラメタをもつかもしれない。データ型ライブラリは,各データ型に適用できる パラメタが何かを定める。

  • 二つの文字列が、あるデータ型の同じ値を表すかどうかを決定することが できる。この機能は,パラメタをもたない。

どちらの機能も,文字列が現れる文脈を用いるかも しれない。例えば,QNameを表すデータ型は名前空間マップを用いる。

次に示す補助的な記法を用いる。

datatypeAllows(u, ln, params, s, cx)

URIuが示すデータ型ライブラリで、文脈cxにおいて解釈される文字列sは、 パラメタparamsをもつデータ型ln の合法的な値であることを意味する。

datatypeEqual(u, ln, s1, cx1, s2, cx2)

URIuが示すデータ型ライブラリで、文脈cx1において解釈される文字列s1と文脈cx2において解釈される文 字列s2は、データ型lnの同じ値をもつことを意味する。

params

パラメタの列を値とする変数

[cx]

パターンを表す開始タグの中では、そのパターン要素の文脈のことを 意味する。

context( u, cx )

cxと同一であるが,デフォルトの 名前空間がuである点だけが異なる文脈を構築する。もし、 uが空文字列であれば、構築された文脈はデフォルト名前 空間をもたない。

datatypeEqual関数は、反射的・推移的・対称的でなけれ ばならない。すなわち、次の推論規則が成立しなくてはならない。

(datatypeEqual reflexive)
datatypeAllows(u, ln, params, s, cx)

datatypeEqual(u, ln, s, cx, s, cx)
(datatypeEqual transitive)
datatypeEqual(u, ln, s1, cx1, s2, cx2)    datatypeEqual(u, ln, s2, cx3, s3, cx3)

datatypeEqual(u, ln, s1, cx1, s3, cx3)
(datatypeEqual symmetric)
datatypeEqual(u, ln, s1, cx1, s2, cx2)

datatypeEqual(u, ln, s2, cx2, s1, cx1)

dataパターン及び valueパターンの意味を次のとおりに定める。

(value)
datatypeEqual(u1, ln, s1, cx1, s2, context( u2, cx2 ))

cx1 |- { }; s1 =~ <value datatypeLibrary="u1" type="ln" ns="u2" [cx2]> s2 </value>
(data 1)
datatypeAllows(u, ln, params, s, cx)

cx |- { }; s =~ <data datatypeLibrary="u" type="ln"> params </data>
(data 2)
datatypeAllows(u, ln, params, s, cx)    not(cx |- a; s =~ p)

cx |- { }; s =~ <data datatypeLibrary="u" type="ln"> params <except> p </except> </data>

6.2.9. 組み込みデータ型ライブラリ

空のURIは、特別の組み込みデータ型ライブラリを特定す る。このライブラリは,二つのデータ型stringtokenを提供する。どちらのデータ型もパラメタをもつこ とはできない。

s1 = s2

s1s2 が同一であることを意味する。

normalizeWhiteSpace( s )

文字列sの先頭と末尾にある 空白文字を取り除き、 それ以外の空白文字の列を単一のスペース文字に置き換えたものを返す。

二つの組み込みデータ型の意味を次のとおりに定める。

(string allows)
datatypeAllows("", "string", ( ), s, cx)
(string equal)
datatypeEqual("", "string", s, cx1, s, cx2)
(token allows)
datatypeAllows("", "token", ( ), s, cx)
(token equal)
normalizeWhiteSpace( s1 ) = normalizeWhiteSpace( s2 )

datatypeEqual("", "token", s1, cx1, s2, cx2)

6.2.10. listパターン

次に示す補助的な記法を用いる。

split( s )

空白によって区切られたトークンの一つ一つに対して一つのs文字列をもつ列を返す。返された列に含まれる各文字列は、 空ではなく空白を含まない。

listパターンの意味を次のとおりに定める。

(list)
cx |- { }; split( s ) =~ p

cx |- { }; s =~ <list> p </list>

注意

直前に示した推論規則において、 パターンと照合される列は連続するいくつかの文字列を含んでも よいことに注意。

6.3. 妥当性

要素がスキーマに照らして妥当であるのは どんな場合かを定義する。次に示す補助的な記法を用いる。

e

要素を値とする変数

valid(e)

要素eが 文法に照らして妥当であることを意味する

start() = p

文法が <start> p </start> を含むことを意味する

要素が妥当であるのは,この要素に空の属性集合を組み合 わせたものが、文法のstartパターンにマッチするとき である。

(valid)
start() = p    cx |- { }; e =~ p

valid(e)

6.4. 例

e0の値が

element( name( "", "foo" ), cx0, { }, m )

であると仮定する。ここで,m

e1, e2

でありe1

element( name( "http://www.example.com/n1", "bar1" ), cx1, { }, ( ) )
element( name( "http://www.example.com/n2", "bar2" ), cx2, { }, ( ) )

である。

cx0, cx1及びcx2が適切に定義されているとすれば,これらは 項2.1に示す文書を表現する。

スキーマ 項5.1に照らして e0が妥当であることをいかにして示すかを 説明する。このスキーマは,次の命題(複数)と同等である。

start() = <ref name="foo"/>
deref("foo.element") = <element> <name ns=""> "foo" </name> <group> <ref name="bar1"/> <ref name="bar2"/> </group> </element>
deref("bar1.element") = <element> <name ns="http://www.example.com/n1"> "bar1" </name> <empty/> </element>
deref("bar2.element") = <element> <name ns="http://www.example.com/n2"> "bar2" </name> <empty/> </element>

名前クラスnc1

<name ns="http://www.example.com/n1"> "bar1" </name>
<name ns="http://www.example.com/n2"> "bar2" </name>

であるとする。

このとき、項6.1の推論規則(name)によって,

name( "http://www.example.com/n1", "bar1" ) in nc1
name( "http://www.example.com/n2", "bar2" ) in nc2

が得られる。

項6.2.3の推論規則(empty) によって、

cx1 |- { }; ( ) =~ <empty/>
cx2 |- { }; ( ) =~ <empty/>

が得られる。

cx0 |- { }; e1 =~ <ref name="bar1"/>

が得られる。

任意の文脈 が利用できるので,cx0を選んでいることに注意する。

cx0 |- { }; e2 =~ <ref name="bar2"/>

が得られる。

cx0 |- { }; e1, e2 =~ <group> <ref name="bar1"/> <ref name="bar2"/> </group>

が得られる。

項6.2.7の推論規則(element)によって、

cx3 |- { }; element( name( "", "foo" ), cx0, { }, m ) =~ <ref name="foo"/>

が得られる。ここで,cx3 は任意の文脈である。

valid(e0)

が得られる。

7. 制限

次に示す制約は文法が項5で規定した単純な形式に変換された後にすべて確認される。 これらの制限は、利用者の誤りの検出と実装の簡略化を目的とする。

7.1. 文脈上の制限

この節では、スキーマにおいて要素が出現できる位置につ いての制限を、祖先要素の名前に基づいて規定する。これらの制限を規定する ために禁止された経路の概念を使用する。経路は /又は// で区切られたNCName の並 びとなる。

  • ある要素が経路 x にマッチするのは, その要素のローカル名が x のときに限る。 ここで x はNCNameとする。

  • ある要素が経路 x/p にマッチするのは, この要素の局所名が x であり、この要素のある子がpにマッチするときに限る。ここで x はNCNameで、p は経路とする。

  • ある要素が経路 x//p にマッチするのは, この要素の局所名が x であり、この要素のある子孫要素が p にマッチするときに限る。ここで x はNCNameで、 p は経路とする。

たとえば,要素

<foo>
  <bar>
    <baz/>
  </bar>
</foo>

は,経路 foo, foo/bar, foo//bar, foo//baz, foo/bar/baz, foo/bar//baz及びfoo//bar/baz にマッチするが, foo/baz又はfoobar にはマッチしない。

単純な形式に変換された後の正しい RELAX NGスキーマは, 禁止された経路にマッチする要素を含んではならない。

7.1.1. attributeパターン

次に示す経路は禁止されている。

  • attribute//ref
  • attribute//attribute

7.1.2. oneOrMoreパターン

次に示す経路は禁止されている。

  • oneOrMore//group//attribute
  • oneOrMore//interleave//attribute

7.1.3. listパターン

次に示す経路は禁止されている。

  • list//list
  • list//ref
  • list//attribute
  • list//text
  • list//interleave

7.1.4. data中のexceptパターン

次に示す経路は禁止されている。

  • data/except//attribute
  • data/except//ref
  • data/except//text
  • data/except//list
  • data/except//group
  • data/except//interleave
  • data/except//oneOrMore
  • data/except//empty

注意

これはdataを親にもつexcept要素は data, value, 及び choice 要素だけを含むことができることを意味する。

7.1.5. start要素

次に示す経路は禁止されている。

  • start//attribute
  • start//data
  • start//value
  • start//text
  • start//list
  • start//group
  • start//interleave
  • start//oneOrMore
  • start//empty

7.2. 文字列の並び

RELAX NG は次のようなパターンを許可しない。

<element name="foo">
  <group>
    <data type="int"/>
    <element name="bar">
      <empty/>
    </element>
  </group>
</element>

次のようなパターンもまた許可しない。

<element name="foo">
  <group>
    <data type="int"/>
    <text/>
  </group>
</element>

一般的に説明する。 もし要素又は属性の内容のためのパターンが

  • 子にマッチすることができるパターン (element, data, value, list 又は text パターン)及び

  • 一つの文字列にマッチするパターン (data, value 又は list パターン)

含んでいるなら,これら二つのパターンが同時に適用されることはない。

この規則は list パターン中に出現するパターンには適用しない。

この規則を形式化するために,内容種別の概念を用いる。 要素の内容として許可されるパターンは emtpy, complex, simple の三つの内容種別のうち一つをもつ。 次に示す記法を用いる。

empty( )

empty内容種別を返す

complex( )

complex内容種別を返す

simple( )

simple内容種別を返す

ct

内容種別を値とする変数

groupable(ct1, ct2)

内容種別ct1ct2 がグループ化可能であることを示す。

empty内容種別は どの内容種別ともグループ化可能である。 さらに, complex内容種別はcomplex内容種別とグループ化可能である。 次に示す規則はこれを形式化している。

(group empty 1)
groupable(empty( ), ct)
(group empty 2)
groupable(ct, empty( ))
(group complex)
groupable(complex( ), complex( ))

いくつかのパターンは内容種別をもつ。 次に示す補助的な記法を用いる。

p :c ct

パターン p は 内容種別ct をもつことを示す

max( ct1, ct2 )

ct1ct2 の大きいほうを返す ここで、内容種別はempty( ), complex( ), simple( )empty( ), complex( ), simple( ) の順に大きいとする。

次に示す規則は,パターンが内容種別をもつのはどんな場合か,その場合の内容種別は何かを定義している。

(value)
<value datatypeLibrary="u1" type="ln" ns="u2"> s </value> :c simple( )
(data 1)
<data datatypeLibrary="u" type="ln"> params </data> :c simple( )
(data 2)
p :c ct

<data datatypeLibrary="u" type="ln"> params <except> p </except> </data> :c simple( )
(list)
<list> p </list> :c simple( )
(text)
<text/> :c complex( )
(ref)
<ref name="ln"/> :c complex( )
(empty)
<empty/> :c empty( )
(attribute)
p :c ct

<attribute> nc p </attribute> :c empty( )
(group)
p1 :c ct1    p2 :c ct2    groupable(ct1, ct2)

<group> p1 p2 </group> :c max( ct1, ct2 )
(interleave)
p1 :c ct1    p2 :c ct2    groupable(ct1, ct2)

<interleave> p1 p2 </interleave> :c max( ct1, ct2 )
(oneOrMore)
p :c ct    groupable(ct, ct)

<oneOrMore> p </oneOrMore> :c ct
(choice)
p1 :c ct1    p2 :c ct2

<choice> p1 p2 </choice> :c max( ct1, ct2 )

注意

項7.1.4 においていくつかの経路を禁止したため,規則 (data2) の条件は冗長である。

制限を記述する準備ができた。次に示す記法を用いる。

incorrectSchema()

スキーマが正しくないことを示す

要素パターンの内容として出現するパターンはすべて内容種別を持たなければならない。

(element)
deref(ln) = <element> nc p </element>    not(p :c ct)

incorrectSchema()

7.3. 属性の制限

属性の重複は許可しない。 より正確には,パターン <group> p1 p2 </group> 又は <interleave> p1 p2 </interleave> に対して, p1 中で出現する attribute パターンの名前クラスと p2 中で出現する attribute パターンの名前クラスの 両方に属する名前があってはならない。 パターン p1 がパターン p2 中に出現するのは次の場合である

  • p1p2である場合, 又は

  • p2choice, interleave, group 又は oneOrMore要素であり p1p2 の片方又は両方の子の中に出現する場合

無限名前クラスに使われる属性は繰り返されなければならない。 より正確には, anyName 又は nsName 子孫要素をもつ attribute 要素は oneOrMore 祖先要素を持たなければならない。

注意

この制限は否定下の閉包のために必要である。

7.4. interleave の制限

<interleave> p1 p2 </interleave> パターンに対して,

  • p1 中に出現する ref パターンに参照されている element パターンの名前クラスと p2 中に出現する ref パターンに参照されている element パターンの名前クラスと の両方に属する名前があってはならない。

  • text パターンは p1p2 の両方に出現してはならない。

パターンが他のパターンの中に出現するのはどんな場合かは項7.3で定義した。

8. 適合性

適合するRELAX NG 妥当性検証器は、XML 文書が正しいRELAX NG スキーマであるかどうか決定できなければならない。 適合するRELAX NG 妥当性検証器は、XML 文書が正しいRELAX NG スキーマに照らして妥当かどうか決定できなければならない。

前段落で述べた要求は、妥当性検証器が実装していないデータ型ライブラリを スキーマが使用していたときには適用されない。 適合するRELAX NG 妥当性検証器は 項6.2.9 で規定した組込みデータ型ライブラリを実装することだけが要求される。 RELAX NG に適合すると主張する妥当性検証器は 実装するデータ型ライブラリを文書化するのが望ましい。 スキーマが externalRef 又は include 要素を持っており、妥当性検証器がそのURI によって特定される資源を取り出せないとき, 又は取り出した資源から要素を構築できないときも前段落の要求は適用されない。 RELAX NG に適合すると主張する妥当性検証器については、 URI 参照の取扱い能力を文書化しておくことが望ましい。

A. RELAX NGのためのRELAX NGスキーマ

<grammar datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
  ns="http://relaxng.org/ns/structure/1.0"
  xmlns="http://relaxng.org/ns/structure/1.0">

  <start>
    <ref name="pattern"/>
  </start>

  <define name="pattern">
    <choice>
      <element name="element">
        <choice>
          <attribute name="name">
            <data type="QName"/>
          </attribute>
          <ref name="open-name-class"/>
        </choice>
        <ref name="common-atts"/>
        <ref name="open-patterns"/>
      </element>
      <element name="attribute">
        <ref name="common-atts"/>
        <choice>
          <attribute name="name">
            <data type="QName"/>
          </attribute>
          <ref name="open-name-class"/>
        </choice>
        <interleave>
          <ref name="other"/>
          <optional>
            <ref name="pattern"/>
          </optional>
        </interleave>
      </element>
      <element name="group">
        <ref name="common-atts"/>
        <ref name="open-patterns"/>
      </element>
      <element name="interleave">
        <ref name="common-atts"/>
        <ref name="open-patterns"/>
      </element>
      <element name="choice">
        <ref name="common-atts"/>
        <ref name="open-patterns"/>
      </element>
      <element name="optional">
        <ref name="common-atts"/>
        <ref name="open-patterns"/>
      </element>
      <element name="zeroOrMore">
        <ref name="common-atts"/>
        <ref name="open-patterns"/>
      </element>
      <element name="oneOrMore">
        <ref name="common-atts"/>
        <ref name="open-patterns"/>
      </element>
      <element name="list">
        <ref name="common-atts"/>
        <ref name="open-patterns"/>
      </element>
      <element name="mixed">
        <ref name="common-atts"/>
        <ref name="open-patterns"/>
      </element>
      <element name="ref">
        <attribute name="name">
          <data type="NCName"/>
        </attribute>
        <ref name="common-atts"/>
        <ref name="other"/>
      </element>
      <element name="parentRef">
        <attribute name="name">
          <data type="NCName"/>
        </attribute>
        <ref name="common-atts"/>
        <ref name="other"/>
      </element>
      <element name="empty">
        <ref name="common-atts"/>
        <ref name="other"/>
      </element>
      <element name="text">
        <ref name="common-atts"/>
        <ref name="other"/>
      </element>
      <element name="value">
        <optional>
          <attribute name="type">
            <data type="NCName"/>
          </attribute>
        </optional>
        <ref name="common-atts"/>
        <text/>
      </element>
      <element name="data">
        <attribute name="type">
          <data type="NCName"/>
        </attribute>
        <ref name="common-atts"/>
        <interleave>
          <ref name="other"/>
          <group>
            <zeroOrMore>
              <element name="param">
                <attribute name="name">
                  <data type="NCName"/>
                </attribute>
                <ref name="common-atts"/>
                <text/>
              </element>
            </zeroOrMore>
            <optional>
              <element name="except">
                <ref name="common-atts"/>
                <ref name="open-patterns"/>
              </element>
            </optional>
          </group>
        </interleave>
      </element>
      <element name="notAllowed">
        <ref name="common-atts"/>
        <ref name="other"/>
      </element>
      <element name="externalRef">
        <attribute name="href">
          <data type="anyURI"/>
        </attribute>
        <ref name="common-atts"/>
        <ref name="other"/>
      </element>
      <element name="grammar">
        <ref name="common-atts"/>
        <ref name="grammar-content"/>
      </element>
    </choice>
  </define>

  <define name="grammar-content">
    <interleave>
      <ref name="other"/>
      <zeroOrMore>
        <choice>
          <ref name="start-element"/>
          <ref name="define-element"/>
          <element name="div">
            <ref name="common-atts"/>
            <ref name="grammar-content"/>
          </element>
          <element name="include">
            <attribute name="href">
              <data type="anyURI"/>
            </attribute>
            <ref name="common-atts"/>
            <ref name="include-content"/>
          </element>
        </choice>
      </zeroOrMore>
    </interleave>
  </define>

  <define name="include-content">
    <interleave>
      <ref name="other"/>
      <zeroOrMore>
        <choice>
          <ref name="start-element"/>
          <ref name="define-element"/>
          <element name="div">
            <ref name="common-atts"/>
            <ref name="include-content"/>
          </element>
        </choice>
      </zeroOrMore>
    </interleave>
  </define>

  <define name="start-element">
    <element name="start">
      <ref name="combine-att"/>
      <ref name="common-atts"/>
      <ref name="open-pattern"/>
    </element>
  </define>

  <define name="define-element">
    <element name="define">
      <attribute name="name">
        <data type="NCName"/>
      </attribute>
      <ref name="combine-att"/>
      <ref name="common-atts"/>
      <ref name="open-patterns"/>
    </element>
  </define>

  <define name="combine-att">
    <optional>
      <attribute name="combine">
        <choice>
          <value>choice</value>
          <value>interleave</value>
        </choice>
      </attribute>
    </optional>
  </define>

  <define name="open-patterns">
    <interleave>
      <ref name="other"/>
      <oneOrMore>
        <ref name="pattern"/>
      </oneOrMore>
    </interleave>
  </define>

  <define name="open-pattern">
    <interleave>
      <ref name="other"/>
      <ref name="pattern"/>
    </interleave>
  </define>

  <define name="name-class">
    <choice>
      <element name="name">
        <ref name="common-atts"/>
        <data type="QName"/>
      </element>
      <element name="anyName">
        <ref name="common-atts"/>
        <ref name="except-name-class"/>
      </element>
      <element name="nsName">
        <ref name="common-atts"/>
        <ref name="except-name-class"/>
      </element>
      <element name="choice">
        <ref name="common-atts"/>
        <ref name="open-name-classes"/>
      </element>
    </choice>
  </define>

  <define name="except-name-class">
    <interleave>
      <ref name="other"/>
      <optional>
        <element name="except">
          <ref name="open-name-classes"/>
        </element>
      </optional>
    </interleave>
  </define>

  <define name="open-name-classes">
    <interleave>
      <ref name="other"/>
      <oneOrMore>
        <ref name="name-class"/>
      </oneOrMore>
    </interleave>
  </define>

  <define name="open-name-class">
    <interleave>
      <ref name="other"/>
      <ref name="name-class"/>
    </interleave>
  </define>

  <define name="common-atts">
    <optional>
      <attribute name="ns"/>
    </optional>
    <optional>
      <attribute name="datatypeLibrary">
        <data type="anyURI"/>
      </attribute>
    </optional>
    <zeroOrMore>
      <attribute>
        <anyName>
          <except>
            <nsName/>
            <nsName ns=""/>
          </except>
        </anyName>
      </attribute>
    </zeroOrMore>
  </define>

  <define name="other">
    <zeroOrMore>
      <element>
        <anyName>
          <except>
            <nsName/>
          </except>
        </anyName>
        <zeroOrMore>
          <choice>
            <attribute>
              <anyName/>
            </attribute>
            <text/>
            <ref name="any"/>
          </choice>
        </zeroOrMore>
      </element>
    </zeroOrMore>
  </define>

  <define name="any">
    <element>
      <anyName/>
      <zeroOrMore>
        <choice>
          <attribute>
            <anyName/>
          </attribute>
          <text/>
          <ref name="any"/>
        </choice>
      </zeroOrMore>
    </element>
  </define>

</grammar>

B. 版0.9からの差分

(省略)

C. RELAX NG TC (参考)

この仕様書は、RELAX NG TCが準備し,公開を 承認した。TCの現在のメンバを次に示す。

  • Fabio Arciniegas
  • James Clark
  • Mike Fitzgerald
  • 川口 耕介
  • Josh Lubell
  • 村田 真
  • Norman Walsh
  • David Webber

文献

引用規定

RFC 2396
T. Berners-Lee, R. Fielding, L. Masinter. RFC 2396: Uniform Resource Identifiers (URI): Generic Syntax. IETF (Internet Engineering Task Force). 1998.
RFC 2732
R. Hinden, B. Carpenter, L. Masinter. RFC 2732: Format for Literal IPv6 Addresses in URL's. IETF (Internet Engineering Task Force), 1999.
RFC 3023
村田 真, S. St.Laurent, D. Kohn. RFC 3023: XML Media Types. IETF (Internet Engineering Task Force), 2001.
XLink
XML 1.0
Tim Bray, Jean Paoli, and C. M. Sperberg-McQueen, Eve Maler, editors. Extensible Markup Language (XML) 1.0 Second Edition. W3C (World Wide Web Consortium), 2000.
XML Infoset
John Cowan, Richard Tobin, editors. XML Information Set. W3C (World Wide Web Consortium), 2001.
XML Namespaces
Tim Bray, Dave Hollander, and Andrew Layman, editors. Namespaces in XML. W3C (World Wide Web Consortium), 1999.

参考文献

RELAX
村田 真. RELAX (Regular Language description for XML). INSTAC (Information Technology Research and Standardization Center), 2001.
TREX
James Clark. TREX - Tree Regular Expressions for XML. Thai Open Source Software Center, 2001.
Tutorial
James Clark, 村田 真, editors. RELAX NG Tutorial. OASIS, 2001.
W3C XML Schema Datatypes
Paul V. Biron, Ashok Malhotra, editors. XML Schema Part 2: Datatypes. W3C (World Wide Web Consortium), 2001.
XML Schema Formal
Allen Brown, Matthew Fuchs, Jonathan Robie, Philip Wadler, editors. XML Schema: Formal Description. W3C (World Wide Web Consortium), 2001.