標準情報 TR X 0029:2000

XML正規言語記述 RELAX コア 解説



1. 公表の趣旨及び経緯

1.1 公表の趣旨

XML(TR X 0008:1999)では,個別のアプリケーションの要求に応じてタグセットを設計する。タグセットの記述には,従来からDTDが用いられてきた。しかし,DTDには次の三つの問題がある。

これらの問題を解決する言語が, 市場では強く望まれており,既に幾つかの提案が出されている。RELAXは,それらの共通機能を実現する標準的な規定である。

1.2 公表の経緯

(財)日本規格協会情報技術標準化研究センター(INSTAC)の"高速Webにおける標準化に関する調査研究委員会"は, その作業グループ(WG3)のXML特別作業グループ(XML-SWG)において, TR X 0008:1998 拡張可能なマーク付け言語(XML)のメンテナンス,TR X 0023:1999 XML名前空間の制定を担当すると共に,RELAXの調査研究を行なって,標準情報(TR)による公表の必要性を提言した。

XML特別作業グループ(XML-SWG)は, 通商産業省工業技術院からの委託を受けて1999年度の活動として, RELAXコアの制定及び標準情報(TR)原案作成を行なった。原案は2000年3月に工業技術院に提出されている。

2. 審議中の重要課題及び懸案事項

2.1 XML Schemaとの関係

W3Cでは,XML Schemaという勧告の制定活動が進行している。XML Schemaは,タグセットを記述するためのスキーマ言語である。

XML Schemaは,DTDが扱う範囲を大きく越えた野心的な規定である。したがって,制定にも実装にも採用にも長い時間を必要とする。XML Schemaのすべての機能を利用するには,SAX又はDOMの拡張も必要になる。

一方,RELAXは制定・実装が容易なことを目標としている。実際,この標準情報(TR)が発行されるときには, 既に実装が幾つか現れている。DTD相当の機能とXML Schemaの豊富なデータ型とをXMLインスタンス構文で表現し,幾つかの独自拡張を行ったものがRELAXになる。

RELAXは,DTDからXML Schemaへの移行を容易にする。RELAXは,DTDにデータ型の情報を付加したものとみなすことができ,DTDから直ちに移行できる。XML Schemaが完成したときには,必要ならRELAXからXML Schemaに移行すればよい。

2.2 構成

名前空間は重要であるが,名前空間を必要としないアプリケーションも数多く存在する。例えば,小規模なEDIは, 名前空間なしに実現可能である。このようなアプリケーションを構築する利用者にとっては,名前空間を含んだ規定よりも,名前空間を含まない規定のほうが,単純で理解しやすい。

この理由によって,RELAXは, Core及びNamespaceの二つの部分に分けて制定する。この標準情報(TR)は,単一の名前空間だけを扱う。複数の名前空間の混在を許すための機能は,RELAX Namespaceとして別の標準情報(TR)が規定する。なお,RELAX Namespaceの制定に際して,この標準情報(TR)を見直す可能性もある。

2.3 曖昧性

RELAX Coreには曖昧性がある。すなわち,一つの文書が与えられたとき,各要素及び属性に対してデータ型・役割・ラベルが一意に決まらず,複数の可能性が存在することがある。

XML文書が合法であるかどうかを判定するだけなら曖昧性は問題にはならないが,プログラミング言語のクラスを生成するなどの用途では問題になることがある。合法であるかの判定のとき,適切なエラーメッセージを出すことが難しくなる。曖昧性については今後さらに検討し,必要に応じてこの標準情報(TR)を改正する可能性がある。

2.3.1 データ型の曖昧性

開始タグ(空要素タグ)を与えられて,属性のデータ型が一意に決まらない。次の例では,タグ名fooの要素が属性barをもつとき,そのデータ型が integerなのかstringなのかが決まらない。

<tag name="foo" role="foo1">
  <attribute name="bar" type="integer"/>
</tag>

<tag name="foo" role="foo2">
  <attribute name="bar" type="string"/>
</tag>

一つの解決案は,一つのタグ名に対して,それがどの役割であるかに関係なく,属性名及びデータ型は一意に決まるように制限することである。その制限を導入すれば,この例は, 文法エラーになる。

しかし,この案は,element要素に影響を及ぼす。例えば,elementによって用いたタグ名は,他の場所で属性を追加することができない。具体的には,次の例は, 文法的に許容されなくなる。titleというタグ名に対して, bar属性をもつ節ともたない節とが存在しているからである。

<tag name="title">
  <attribute name="bar" type="integer"/>
</tag>

<tag name="foo"/>

<elementRule role="foo">
  <sequence>
    <element name="title" type="integer"/>
  </sequence>
<elementRule>

属性だけではなく,要素の文字内容についても曖昧性がある。次の例では,foo要素の内容がintegerなのかstringなのかは確定しない。

<elementRule role="foo" type="integer"/>

<elementRule role="foo" type="string"/>

次の例では,<foo>10</foo>の内容である"10"が混在生け垣モデルによるものか,それともデータ型integerによるものかが確定しない。

<elementRule role="foo" type="integer"/>

<elementRule role="foo">
  <mixed>
    <empty/>
  </mixed>
</elementRule>

一つの解決案は,ある役割に対する一つのelementRuleがデータ型を指定するなら,他のelementRuleも同じデータ型・相を指定しなければならないという制約を設けることである。

2.3.2 役割の曖昧性

一つのタグが複数の役割をもつことがある。次の例では,空要素<foo>の役割がfoo1なのかfoo2なのかが確定しない。

<tag name="foo" role="foo1"/>

<tag name="foo" role="foo2"/>

次の例では,<foo bar="3"/>の役割が確定しない。

<tag name="foo" role="foo1">
  <attribute name="bar" type="integer"/>
</tag>

<tag name="foo" role="foo2">
  <attribute name="bar" type="string"/>
</tag>

データ型の曖昧性及び役割の曖昧性が同時に発生していることに注意。

2.3.3 ラベルの曖昧性

一つの要素に対して,複数のラベルが割り当て可能なことがある。例えば,次のモジュールを考える。

<?xml version="1.0"?>
<module
      moduleVersion="1.0"
      relaxCoreVersion="1.0"
      targetNamespace=""
      xmlns="http://www.xml.gr.jp/xmlns/relaxCore">

  <interface>
    <export label="paraWithFnotes"/>
    <export label="paraWithoutFnotes"/>
  </interface>

  <elementRule role="para" label="paraWithFnotes">
    <mixed>
      <ref label="fnote" occurs="*"/>
    </mixed>
  </elementRule>

  <elementRule role="para" label="paraWithoutFnotes" type="string"/>
  
  <tag name="para"/>  

  <elementRule role="fnote" type="string">

  <tag name="fnote"/>  

</module>

このモジュールと次のXML文書とを照合したとする。

<?xml version="1.0"?>
<para>This is a pargraph.</para>

このpara要素には,ラベルparaWithFnotesとparaWithoutFnotesの両方が割当て可能であり,どちらを選んでもこの文書は合法になる。したがって,ラベルに関する曖昧性がある。

ラベルの曖昧性は,次の照合戦略とも大きく関係する。2.4に示す照合戦略のうち決定的なものを選び,それに適さないモジュールを禁止すれば,曖昧性はなくなる。

2.4 照合戦略

XML文書をRELAXモジュールと照合するには,幾つかの戦略が考えられる。それぞれの戦略は,生け垣オートマトンの変種に相当する。次に,考えられる検証戦略を列挙する。

次では,e0は親要素,e1, e2 ...., enは子供要素を表す。

2.4.1 トップダウン決定的生け垣オートマトン

各要素に対してラベルを一意に決める戦略である。照合は,XML文書のルート要素から末端要素へと進む。

e0の開始タグ及びe0に割り当てられたラベルの二つだけから, e1, e2..., enに割り当てるラベル列を計算する。計算のとき,e1, e2 ..., enにある情報はいっさい見ない。

この戦略はたいへん非力であり,RELAXには利用できない。例えば,次のelementRuleのように,docの内容として,段落の繰り返し及び図の繰り返しの並びを許すことさえできない。

<elementRule role="doc" label="doc-label">
  <sequence>
    <ref label="para-label" occurs="*"/>
    <ref label="fig-label" occurs="*"/>
  </sequence>
</elementRule>

次のXML文書を例に, 説明する。

<doc>
  <para/>
  <fig/>
</doc>

トップダウン決定的生け垣オートマトンでは,<doc>という開始タグ,及びdoc-labelというラベルだけから,子要素e1, e2にラベルをふらなければならない。e1のタグである<para/>及びe2のタグである<fig/>を見ることは許されない。したがって,e1にdoc-labelを,e2にfig-labelをふるという判断はできない。

2.4.2 ボトムアップ決定的生け垣オートマトン

各要素に対してラベルを一意に決める戦略である。照合は,XML文書の末端要素からルート要素へと進む。

e1, e2 ...., enに割り当てられたラベル列 l1, l2, ..., ln, 及びe0の開始タグだけから,e0に割り当てるラベルを計算する。計算のとき,e0にある情報はいっさい見ない。

これは,すべての生け垣正規言語を受理するという意味で強力である。しかし, RELAX Coreに直接利用することはできない。例えば,次の二つのelementRuleを考える。

<elementRule role="foo" label="bar1">
  <ref label="Fnote" occurs="*"/>
</elementRule>

<elementRule role="foo" label="bar2">
  <empty/>
</elementRule>

次の要素fooには,ラベルbar1及びbar2の両方が候補になる。一意に確定することはできない。

<foo></foo>
RELAXモジュールをいったんボトムアップ決定的生け垣オートマトンに変換してから照合することは可能である。しかし,この変換を行ったとき,RELAXモジュールに書かれたラベルは消えてしまう。新たなラベルは,{l1, l2, ..., ln} の形になる(l1, l2, ..., lnはラベル)。各要素に対し,新たなラベルは一意に決まるが,もともとRELAXモジュールにあったラベルは一意には決まらない。

2.4.3 トップダウン非決定的生け垣オートマトン

各要素に対して, 複数のラベルを付与する戦略である。ただし,ラベルの割当てかたを一つ見つけたときに終了するという実装も可能である。照合は,XML文書のルート要素から末端要素へと進む。

e0の開始タグ及びe0に割り当てられたラベル集合の二つだけから,e1, e2..., enに割り当てるラベル列の集合を求める。計算のとき,e1, e2 ..., enにある情報は いっさい見ない。説明のため,ラベル列 (l1, 1, l2, 1, ..., ln, 1)とラベル列(l1, 2, l2, 2, ..., ln, 2)とからなる集合が求まったものとする。

次に,この集合に含まれるラベル列一つずつに対して,計算を実行する。この例では,まずe1にl1, 1を割り当て, e2にl2, 1を割り当て,enにln,1を割り当てて照合する。その後で,e1にl1, 2を割り当て, e2にl2, 2を割り当て, enにln, 2を割り当てて照合する。どちらかの照合が成功すれば,照合は全体としても成功する。

先のelementRuleを,次にもう一度示す。このelementRuleを例に,照合がどのように行われるかを説明する。

<elementRule role="doc" label="doc-label">
  <sequence>
    <ref label="para-label" occurs="*"/>
    <ref label="fig-label" occurs="*"/>
  </sequence>
</elementRule>

入力文書として, 次のものを仮定する。

<doc>
  <para/>
  <para/>
  <fig/>
  <fig/>
</doc>

docの子要素列に割り当てるラベル列として,次の五つの可能性がある。

これらの可能性をすべて試し,どれかひとつでも照合が成功すれば,全体としても照合は成功する。

2.4.4 ボトムアップ非決定的生け垣オートマトン

各要素に対して複数のラベルを付与する戦略である。照合は,XML文書の末端要素からルート要素へと進む。

一見するとたいへん難しく思えるが,実装はさほど困難ではない。これまでに開発されているRELAX Coreプロセサのほとんどが, この戦略を採用している。

e1, e2 ...., enに割り当てられたラ ベル集合{l1, 1, l1, 2, ...}, {l2, 1, l2, 2, ...}, {l3, 1, l3, 2, ...}, ..., {ln, 1, ln, 2, ...} 及びe0の開始タグだけから,e0に割り当てるラベル集合を計算する。計算のとき,e0にある情報はいっさい見ない。

次の例を用いて,照合がどのように行われるかを説明する。

<?xml version="1.0"?>
<module
      moduleVersion="1.0"
      relaxCoreVersion="1.0"
      targetNamespace=""
      xmlns="http://www.xml.gr.jp/xmlns/relaxCore">

  <interface>
    <export label="doc"/>
  </interface>

  <elementRule role="doc">
    <ref label="bar1" occurs="+"/>
    <ref label="bar2" occurs="*"/>
  </elementRule>

  <tag name="doc"/>

  <elementRule role="foo" label="bar1">
    <ref label="Fnote" occurs="*"/>
  </elementRule>
 
  <elementRule role="foo" label="bar2">
    <empty/>
  </elementRule>

  <tag name="foo"/>
</module>

入力となるXML文書として,次のものを仮定する。

<?xml version="1.0"?>
<doc>
  <foo/>
  <foo/>
</doc>

まず,末端要素である二つの<foo/>にラベルを割り当てる。どちらにも, bar1及びbar2の両方を割り当てることができる。

次に,ルート要素docにラベルを割り当てる。どちらの<foo/>にも bar1 が割り当てられているので,1番目のelementRuleによってラベルdocを割り当てることができる。1番目の<foo/>にbar1を割り当て,2番目の<foo/>にbar2を割り当てたときも同様である。どちらにもbar2を割り当てたときは,何のラベルを割り当てることもできない。結局,ルート要素 docに割り当てられるラベルは, docだけである。

2.4.5 DTD

各要素に対してラベルを一意に決める戦略である。照合は,XML文書のルート要素から末端要素へと進む。

DTDでは,ラベルとタグ名とが区別されていない。この点において,DTDの表現力はRELAXより大きく劣る。タグ名が同じなら,内容モデルも同じになってしまうからである。

DTDでは,e0の開始タグだけから,タグ名の列(= ラベル列)の正規 集合が定まる。これを,e1, e2..., enのタグ名と照合する。

トップダウン決定的生け垣オートマトンの場合と異なり,e1, e2 ..., enのタグ名を見ることが許されている。

例として,次の要素型宣言を考える。

<!ELEMENT doc (para*,fig*)>

e0のタグ名がdocで,e0はe 1と e2を子要素としてもっているとする。ラベル列(para, para), (para, fig), (fig, fig)の三つを生成する必要はなく,e1のタグ名及びe2のタグ名からラベル列は一意に決まる。

2.4.6 先読み付きトップダウン決定的生け垣オートマトン

各要素に対してラベルを一意に決める戦略である。照合は,XML文書のルート要素から末端要素へと進む。トップダウン決定的生け垣オートマトンと異なるのは,子要素のタグ名を見ることが許されているという点である。

この戦略には,理論的な根拠がない。しかし,ボトムアップ生け垣オートマトンの表現力の一部を得ることができる。DSD [Document Structure Description] という規定が,この戦略を採用している。

親要素e0の開始タグ及びe0に割り当てられたラベルの二つだけではなく,子要素e1, e2..., enの開始タグも見て,これらに割り当てるラベルを計算する。

この戦略が有効に機能する例を示す。まず,RELAXモジュールを示す。

<?xml version="1.0"?>
<module
      moduleVersion="1.0"
      relaxCoreVersion="1.0"
      targetNamespace=""
      xmlns="http://www.xml.gr.jp/xmlns/relaxCore">

  <interface>
    <export label="doc"/>
  </interface>

  <elementRule role="doc">
    <ref label="paraWithoutFnotes"/>
    <choice occurs="*">
      <ref label="paraWithFnotes"/>
      <ref label="fnote"/>
    </choice>
  </elementRule>

  <tag name="doc"/>

  <elementRule role="para" label="paraWithFnotes">
    <mixed>
      <ref label="fnote" occurs="*"/>
    </mixed>
  </elementRule>

  <elementRule role="para" label="paraWithoutFnotes" type="string"/>
  
  <tag name="para"/>  

  <elementRule role="fnote" type="string">

  <tag name="fnote"/>  
 
</module>

次に,XML文書を示す。

<?xml version="1.0"?>
<doc>
    <para/>
    <para><fnote/></para>
</doc>

まず,文書のルート要素docと,export要素のlabel属性とから,ルート要素のラベルがdocであることが決まる。

二つの子要素の開始タグを見ることが許されているので,これらが役割paraだけをもつことが決まる。この役割をもつ要素に対して割り当て可能なラベルは, paraWithFnotes及びparaWithoutFnotesであることが,すべてのelementRuleを調べることによって分かる。

先頭のelementRuleの要素生け垣モデルは,先頭のラベルとしてparaWithoutFnotesだけを許している。para要素にラベルparaWithoutFnotesが割り当て可能なことは既に確認しているから,1番目の子要素のラベルは, paraWithoutFnotesであることが分かる。

2番目以降のラベルとして,先頭のelementRuleの要素生け垣モデルは, paraWithFnotesとfnoteを許している。ラベルfnoteをpara要素に割り当てることはできないので,2番目の子要素のラベルはparaWithFnotesであることが分かる。

この例では,同じ役割をもつ二つの要素に異なるラベルを割り当てていることに注意。

先頭のelementRuleが, 次のとおり変更されたと仮定する。

  <elementRule role="doc">
    <ref label="paraWithoutFnotes" occurs="*"/>
    <ref label="paraWithFnotes" occurs="*"/>
  </elementRule>

先のXML文書を用いて,このRELAXモジュールが扱えないことを示す。二つの子要素に割り当て可能なラベルはparaWithFnotesとparaWithoutFnotesであることが分かるまでは,前回と変わらない。

変更したelementRuleの要素生け垣モデルは,先頭のラベルとして, paraWithFnotes及びparaWithoutFnotesの両方を許している。したがって,ラベルを一意に決定することはできない。

なお,このRELAXモジュールも, ボトムアップ非決定的生け垣オートマトンでは問題なく実行することができる。

2.4.7 トップダウンl-r-決定的生け垣オートマトン

各要素に対してラベルを一意に決める戦略である。厳密な理論的な根拠があり,先読み付きトップダウン決定的生け垣オートマトンより強い表現力をもつ。

トップダウンl-r-決定的生け垣オートマトンは,[Podelski and Nivat]によって導入されたものである。原論文の定義は数学的なものであり,実際のアルゴリスムは与えられていない。この戦略については,さらに調査する必要がある。

2.5 モジュール化

単一の名前空間だけを扱うDTDにおいても,巨大なもの,例えばXHTML Modularization, TEI, Doc Bookは幾つかのモジュールに分割されている。小さなモジュールは, 分かりやすくなるというだけではなく,モジュールを取捨選択して組み合わせることによって多様な要求に応じられるという利点をもつ。

しかし,このモジュール分割を行うためには,あるモジュールで記述した内容を別のモジュールから変更することが必要になる。次に,その例を示す。

現在のこの標準情報(TR)は,これらの要求を満たしてなく,今後の課題として残されている。現在の規定で可能なのは,次の二つである。

これらだけでは,前述の要求をすべて満たすことはできない。

解決方法の候補として次がある。これらについては,RELAX Namespaceと併行して検討する。

3. 参考文献

a) RELAX公式サイト, http://www.xml.gr.jp/relax

b) RELAX開発者日本語メーリングリスト, http://www2.xml.gr.jp/1ml_main.html?MLID=relax-dev-j

c) RELAX開発者英語メーリングリスト,http://www.egroups.com/group/reldeve

d) Document Structure Description, Nils Klarlund, Anders Moller, and Michael I. Schwartzbach, http://www.brics.dk/DSD/. 2000

e) Minimal Ascending and Descending Tree Automata, Maurice Nivant and Andreas Podelski, SIAM Journal on Computing, Volume 26, Number 1 pp. 39-58, 1997

f) W3C (World Wide Web Consortium), XML Schema Part 1, W3C Working Draft, eds. Henry Thompson, David Beech, Murray Maloney, Noah Mendelsohn, http://www.w3.org/TR/xmlschema-1. 2000

g) W3C (World Wide Web Consortium), XHTMLTM 1.1 - Module-based XHTML, W3C Working Draft, ed. Murray Altheim, Shane McCarron, http://www.w3.org/TR/xhtml1.1

h) W3C (World Wide Web Consortium), Modularization of XHTMLTM, W3C Working Draft, ed. Murray Altheim, Frank Boumphrey, Sam Dooley, Shane McCarron, Ted Wugofski, http://www.w3.org/TR/xhtml-modularization

i) W3C (World Wide Web Consortium), Building XHTMLTM Modules , W3C Working Draft, ed. Murray Altheim, Shane McCarron, http://www.w3.org/TR/xhtml-building

4. 原案作成委員会

この標準情報(TR)の原案を作成した(財)日本規格協会情報技術標準化研究センター(INSTAC)の高速Webにおける標準化に関する調査研究委員会, 作業グループ(WG3)及びXML特別作業グループ(XML-SWG)の委員構成を, その順に次に示す。

高速Webにおける標準化に関する調査研究委員会
氏名 所属
(委員長) 池田 克夫 京都大学
(幹事) 鯵坂 恒夫 和歌山大学
(幹事) 小町 祐史 松下電送システム株式会社
(幹事) 平山 亮 ヒューレット・パッカード日本研究所
内山 光一 株式会社東芝
久保田 靖夫 大日本印刷株式会社
黒川 利明 株式会社CSK
斎藤 伸雄 凸版印刷株式会社
澤田 位 財団法人日本規格協会
八田 勲 通商産業省工業技術院標準部
二本松 勝 株式会社日立製作所
氏兼 裕之 通商産業省機械情報産業局
古瀬 幸広 立教大学
松本 充司 早稲田大学
柳町 昭夫 株式会社NHKアイテック
(事務局) 山中 正幸 財団法人日本規格協会


作業グループ(WG3)
氏名 所属
(主査) 小町 祐史 松下電送システム株式会社
(幹事) 内山 光一 株式会社東芝
奥井 康弘 株式会社日本ユニテック
上村 圭介 国際大学グローバルコミュニケーションセンター
北野 敬介 日本サン・マイクロシステムズ株式会社
黒川 利明 株式会社CSK
郡山 龍 株式会社アプリックス
澤田 位 財団法人日本規格協会
湯沢 広吉 通商産業省機械情報産業局
内藤 広志 大阪工業大学
乃木 篤 株式会社CSK
田川 淳 通商産業省工業技術院標準部
オブザーバ 浅利 千鶴 浅利会計事務所
オブザーバ 山東 滋 株式会社日立製作所
オブザーバ 稲垣 博人 日本電信電話株式会社
オブザーバ 荻原 崇弘 通商産業省機械情報産業局
(事務局) 山中 正幸 財団法人日本規格協会


XML特別作業グループ(XML-SWG)
氏名 所属
(主査) 村田 真 富士ゼロックス情報システム株式会社
内山 光一 株式会社東芝
小町 祐史 松下電送システム株式会社
檜山 正幸 檜山オフィス
奥井 康弘 株式会社日本ユニテック
高橋 亨 株式会社日立製作所
川俣 晶 株式会社ピーデー
上村 圭介 国際大学グローバルコミュニケーションセンター
今郷 詔 株式会社リコー

この標準情報(TR)の作成に際しては, 原案作成委員会委員以外の次の方々から大きな貢献をいただいた。

氏名 所属
山本 春声
浅海 智晴 じゃばじゃば主宰
川口 耕介 有限会社Swift
小崎 資広 松下AVCマルチメディアソフト株式会社
難波 亮丞
米倉 宏治 日本電気株式会社
三木 大知
Eve L. Maler Sun Microsystems, Inc.

5. チュートリアル

5.1 RELAXの概要

RELAXは,XMLベースの言語を記述するための規定である。例えば,XHTML 1.0 は, XMLベースの言語なので,RELAXで記述することができる。RELAXによる記述をRELAX文法という。

5.1.1 DTDとの比較

従来用いられてきたDTD(Document Type Definition)と比べて,RELAXは次の特徴を備えている。

5.1.2 RELAXプロセサ

RELAXプロセサによって,XML文書をRELAX文法と照合することができる。 RELAXプロセサへの入力は,XML文書とRELAX文法である。正確には,RELAXプロセサは, XML文書及びRELAX文法を直接扱うのではなく,XMLプロセサがこれらを処理したあとの出力を扱う。

XML文書がこのRELAX文法に照らして合法かどうかを, RELAXプロセサは報告する。RELAXプロセサは,他にも診断メッセージを出すことがある。RELAXプロセサには,これ以外の出力はない。

5.1.3 RELAXの構成

RELAXは,RELAX Core及びRELAX Namespaceの二つから成る。RELAX Coreは,一つの名前空間にある要素及びその属性を扱う。RELAX Coreは,XML Schema Part 2のデータ型を採用している。RELAX Namespaceは,RELAX Coreで書かれた複数のモジュールを組み合わせ,複数の名前空間を扱う。

5.2 XML DTDからの移行(パラメタ実体なし)

ここでは,パラメタ実体を使わない範囲のDTDをRELAXにどう移行するかを示す。

5.2.1 モジュールの例

RELAXの概要を示すため,あるDTDをRELAXのモジュールとして書き直すことにする。

まずDTDを示す。title要素のnumber属性は整数だけに制限したいが,DTDはこの制限を表現できない。

<!ELEMENT doc   (title, para*)>

<!ELEMENT para  (#PCDATA | em)*>

<!ELEMENT title (#PCDATA | em)*>

<!ELEMENT em    (#PCDATA)>

<!ATTLIST para
  role NMTOKEN #IMPLIED
>

<!ATTLIST title  
  role   NMTOKEN #IMPLIED
  number CDATA   #IMPLIED
>

次にRELAXモジュールを示す。number属性は整数であると指定されている。

<module
      moduleVersion="1.2"
      relaxCoreVersion="1.0"
      targetNamespace=""
      xmlns="http://www.xml.gr.jp/xmlns/relaxCore">

  <interface>
    <export label="doc"/>
  </interface>

  <elementRule role="doc">
    <sequence>
      <ref label="title"/>
      <ref label="para" occurs="*"/>
    </sequence>
  </elementRule>
  
  <elementRule role="para">
    <mixed>
      <ref label="em" occurs="*"/>
    </mixed>
  </elementRule>
  
  <elementRule role="title">
    <mixed>
      <ref label="em" occurs="*"/>
    </mixed>
  </elementRule>

  <elementRule role="em" type="string"/>
  
  <tag name="doc"/>

  <tag name="para">
    <attribute name="role" type="NMTOKEN"/>
  </tag>
  
  <tag name="title">
    <attribute name="role" type="NMTOKEN"/>
    <attribute name="number" required="true" type="integer"/>
  </tag>

  <tag name="em"/>

</module>

次に,この例に含まれる構文を説明する。

5.2.2 module要素

RELAX文法は,幾つかのモジュールを組み合わせたものである。名前空間が一つだけで,それほど大規模でない文法なら,一つのモジュールがそのままRELAX文法になる。モジュールは, module要素によって表現される。

<module
      moduleVersion="1.2"
      relaxCoreVersion="1.0"
      targetNamespace=""
      xmlns="http://www.xml.gr.jp/xmlns/relaxCore">
  ...
</module>

moduleVersion属性は,このモジュールの版数を表す。この例では,"1.2"である。

relaxCoreVersion属性は,RELAX Core自体の版数を表す。現在は必ず"1.0"である。

targetNamespace属性は,このモジュールが扱う名前空間を指定する。この例では,""を指定している。

RELAX Coreのための名前空間名は, http://www.xml.gr.jp/xmlns/relaxCoreである。

5.2.3 interface要素

moduleの先頭には, interface要素が入る。一つのモジュールには, interface要素が一つだけ存在する。

<module
      moduleVersion="1.2"
      relaxCoreVersion="1.0"
      targetNamespace=""
      xmlns="http://www.xml.gr.jp/xmlns/relaxCore">

  <interface>
    ...
  </interface>
  ...
</module>

a) export要素

interface要素の中にはexport要素が幾つか入る。

<export label="foo"/>

export要素label属性の値は,ルートになり得る要素型である。export要素は複数あっても構わない。

次の例は,要素型foo及びbarがルートになり得ることを表している。

<interface>
  <export label="foo"/>
  <export label="bar"/>
</interface>

5.2.4 要素型宣言

XMLでいう要素型宣言(<!ELEMENT ...>)は, elementRule要素によって表現される。 elementRulerole属性は,要素型の名前を指定する。 elementRuleは,interfaceの後に幾つでも書くことができる。

<elementRule role="element-type-name">
  ...hedge model...
</elementRule>

elementRule要素は,生け垣モデルをもつことができる。生け垣とは,要素(子孫要素も含む)及び文字データの並びのことである。生け垣モデルとは,どんな生け垣が許されるかを表す制約条件である。

生け垣モデルには,要素生け垣モデル,データ型参照,混在生け垣モデルがある。

5.2.4.1 要素生け垣モデル

要素生け垣モデルは,empty, ref, choice, sequence, none 要素及びoccurs属性によって表現される。要素生け垣モデルは,子供要素の並びとして何を許容するかを表現する。これらの要素の間に, 適当に空白を挿入することができる。

a) empty要素

empty要素は,空の内容を表す。

次のelementRuleを考える。

<elementRule role="foo">
  <empty/>
</elementRule>

このelementRuleは,foo要素の内容が空であることを表している。開始タグの直後に終了タグを置いても,空要素タグを用いても構わない。

<foo/>
<foo></foo>

XMLのEMPTYとは異なり,開始タグ及び終了タグの間に空白だけを置くことも許される。

<foo>  </foo>

emptyは,後述するchoice又はsequenceの中で使用できる。XMLのEMPTYとまったく同じ機能として,データ型emptyStringが用意されている。

次に,要素型foo, foo1, foo2は,empty を生け垣モデルとしてもつelementRuleによって宣言されているとみなして説明する。

b) ref要素

ref要素は,要素型を参照する。例えば,<ref label="foo"/>は,fooという要素型を参照する。

次のelementRuleを考える。

<elementRule role="bar">
  <ref label="foo"/>
</elementRule>

このelementRuleは,bar要素の内容はfoo要素であることを示す。例えば,次のbar要素は, このelementRuleに従っている。

<bar><foo/></bar>

foo要素の前後に空白が入っても構わない。

<bar>
  <foo/>
</bar>

ref要素は,occurs属性をもつことができる。値は,"*", "+", "?"のどれかで,それぞれ0回以上の繰り返し,1回以上の繰り返し,0回又は1回の繰り返しを意味する。

occurs属性に"?"を指定した例を示す。

<elementRule role="bar">
  <ref label="foo" occurs="?"/>
</elementRule>

このelementRuleは,bar要素の内容はfoo要素又は空であることを示す。

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

foo要素の前後に空白が入っても構わない。空の場合にも, 空白を入れることができる。

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

c) choice要素

choice要素は, 選択(XMLにある"|")を表す。choice要素の子供は, 要素生け垣モデルである。choiceも, occurs属性をもつことができる。

choiceを用いたelementRuleの例を, 次に示す。

<elementRule role="bar">
  <choice occurs="+">
    <ref label="foo1"/>
    <ref label="foo2"/>
  </choice>
</elementRule>

このelementRuleは,bar要素の内容がfoo1要素又はfoo2要素の1回以上の繰り返しであることを示している。

<bar><foo2/></bar>
<bar>
  <foo2/>
</bar>
<bar>
  <foo1/>
  <foo2/>
  <foo1/>
</bar>

d) sequence要素

sequence要素は,並び(XMLにある",")を表す。 sequence要素の子供は, 要素生け垣モデルである。 sequenceも, occurs属性をもつことができる。

sequenceを用いたelementRuleの例を次に示す。

<elementRule role="bar">
  <sequence occurs="?">
    <ref label="foo1"/>
    <ref label="foo2"/>
  </sequence>
</elementRule>

このelementRuleは,bar要素の内容が, foo1要素及びfoo2要素の並び,又は空であることを示している。

<bar><foo1/><foo2/></bar>
<bar>
  <foo1/>
  <foo2/></bar>
<bar/>
<bar></bar>
<bar>
  </bar>

e) none要素

none要素は,RELAXではじめて導入されたものであり,何ともマッチしない生け垣モデルである。

<elementRule role="bar">
  <none/>
</elementRule>

このelementRuleは,barの内容としては何も許されないことを示している。

5.2.4.2 データ型参照

elementRuletype属性によって,データ型を参照する内容モデルを書くことができる。文書中に書かれた文字列は,参照されたデータ型と照合される。指定できるのは,XML Schema Part 2で導入されたデータ型の名前,又はRELAXが独自に導入したデータ型の名前である。

typeを用いたelementRuleの例を, 次に示す。

<elementRule role="bar" type="integer"/>

このelementRuleは,bar要素の内容は整数を表現する文字列であることを示している。

<bar>10</bar>

前後に空白を挿入することはできない。すなわち,次の例は許されない。

<bar>
  10
</bar>

5.2.4.3 混在生け垣モデル

mixed要素は,XMLにある混在生け垣モデル(#PCDATA|a|b|...|z)* を大幅に拡張したものである。

<mixed></mixed>との間には,要素生け垣モデルが書ける。要素生け垣モデルを直接書いたときは,要素の間には空白だけが挿入できたが,mixedで囲むことによって,どんな文字でも挿入可能になる。

例えば,次のelementRuleを考える。

<elementRule role="bar">
  <mixed>
    <ref label="foo"/>
  </mixed>
</elementRule>

要素<foo/>は,mixedの中のref要素にマッチする。したがって,次の例は, このelementRuleによって許されている。

<bar>Murata<foo/>Makoto</bar>

次の例に示すとおり, CDATAセクション又は, 文字参照が現れても構わない。

<bar><![CDATA[Murata]]><foo/>Mako&#x74;&#x6F;</bar>

XMLの(#PCDATA | foo1 | foo2)*を表現するには,次のとおりに書く。

<elementRule role="bar">
  <mixed>
    <choice occurs="*">
      <ref label="foo1"/>
      <ref label="foo2"/>
    </choice>
  </mixed>
</elementRule>

生け垣モデル(#PCDATA)を表現するには,二つの方法がある。一つは,データ型stringtype属性で指定する方法である。もう一つは,mixed要素の中に,空のラベル列だけとマッチする要素生け垣モデルを記述する方法である。次にその例を示す。

<elementRule role="bar" type="string"/>
<elementRule role="bar">
  <mixed>
    <empty/>
  </mixed>
</elementRule>

5.2.5 属性リスト宣言

XMLでいう属性リスト宣言(<!ATTLIST ...>)は,tag要素によって表現される。

<tag name="element-type-name">
  ...list of attribute declarations...
</tag>

tag要素は,子供要素としてattribute要素を幾つかもつことができる。

<tag name="element-type-name">
  <attribute ... />
  <attribute ... />
</tag>

一つのattribute要素は,一つの属性を宣言する。 attribute要素の例を次に示す。

<attribute name="age" required="true" type="integer"/>

name属性の値は,宣言される属性名である。この例では, ageが宣言されている。

required属性の値としてtrueが指定された場合は,宣言された属性の省略は許されない。required属性が指定されない場合は省略できる。この例では指定されているので,省略は許されない。

type属性は,データ型名を指定する。 type属性が省略された場合は,stringというデータ型(任意の文字列)が指定されたものとみなされる。

このattribute要素だけからなるtagの例を考える。

<tag name="bar">
  <attribute name="age" required="true" type="integer"/>
</tag>

次の開始タグは, このtagに従っている。

<bar age="39">

次の二つの開始タグは従っていない。1番目の例はage属性を省いている。2番目の例は値が整数ではない。

<bar>
<bar age="bu huo">
<!-- "bu huo" means forty years in Chinese.  In Japan, 
     it is pronounced as "FUWAKU". -->

DTDでは,属性をもたない要素型については,属性リスト宣言を書く必要がない。しかしRELAXでは,属性をもたない場合も空のtagを書く必要がある。例えば要素型barが属性をもたない場合は, 次のとおりに書く。

 <tag name="bar"/>