XML(TR X 0008:1999)では,個別のアプリケーションの要求に応じてタグセットを設計する。タグセットの記述には,従来からDTDが用いられてきた。しかし,DTDには次の三つの問題がある。
(財)日本規格協会情報技術標準化研究センター(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月に工業技術院に提出されている。
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に移行すればよい。
名前空間は重要であるが,名前空間を必要としないアプリケーションも数多く存在する。例えば,小規模なEDIは, 名前空間なしに実現可能である。このようなアプリケーションを構築する利用者にとっては,名前空間を含んだ規定よりも,名前空間を含まない規定のほうが,単純で理解しやすい。
この理由によって,RELAXは, Core及びNamespaceの二つの部分に分けて制定する。この標準情報(TR)は,単一の名前空間だけを扱う。複数の名前空間の混在を許すための機能は,RELAX Namespaceとして別の標準情報(TR)が規定する。なお,RELAX Namespaceの制定に際して,この標準情報(TR)を見直す可能性もある。
RELAX Coreには曖昧性がある。すなわち,一つの文書が与えられたとき,各要素及び属性に対してデータ型・役割・ラベルが一意に決まらず,複数の可能性が存在することがある。
XML文書が合法であるかどうかを判定するだけなら曖昧性は問題にはならないが,プログラミング言語のクラスを生成するなどの用途では問題になることがある。合法であるかの判定のとき,適切なエラーメッセージを出すことが難しくなる。曖昧性については今後さらに検討し,必要に応じてこの標準情報(TR)を改正する可能性がある。
開始タグ(空要素タグ)を与えられて,属性のデータ型が一意に決まらない。次の例では,タグ名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も同じデータ型・相を指定しなければならないという制約を設けることである。
一つのタグが複数の役割をもつことがある。次の例では,空要素<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>
データ型の曖昧性及び役割の曖昧性が同時に発生していることに注意。
一つの要素に対して,複数のラベルが割り当て可能なことがある。例えば,次のモジュールを考える。
<?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に示す照合戦略のうち決定的なものを選び,それに適さないモジュールを禁止すれば,曖昧性はなくなる。
XML文書をRELAXモジュールと照合するには,幾つかの戦略が考えられる。それぞれの戦略は,生け垣オートマトンの変種に相当する。次に,考えられる検証戦略を列挙する。
次では,e0は親要素,e1, e2 ...., enは子供要素を表す。
各要素に対してラベルを一意に決める戦略である。照合は,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をふるという判断はできない。
各要素に対してラベルを一意に決める戦略である。照合は,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モジュールにあったラベルは一意には決まらない。
各要素に対して, 複数のラベルを付与する戦略である。ただし,ラベルの割当てかたを一つ見つけたときに終了するという実装も可能である。照合は,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の子要素列に割り当てるラベル列として,次の五つの可能性がある。
これらの可能性をすべて試し,どれかひとつでも照合が成功すれば,全体としても照合は成功する。
各要素に対して複数のラベルを付与する戦略である。照合は,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だけである。
各要素に対してラベルを一意に決める戦略である。照合は,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のタグ名からラベル列は一意に決まる。
各要素に対してラベルを一意に決める戦略である。照合は,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モジュールも, ボトムアップ非決定的生け垣オートマトンでは問題なく実行することができる。
各要素に対してラベルを一意に決める戦略である。厳密な理論的な根拠があり,先読み付きトップダウン決定的生け垣オートマトンより強い表現力をもつ。
トップダウンl-r-決定的生け垣オートマトンは,[Podelski and Nivat]によって導入されたものである。原論文の定義は数学的なものであり,実際のアルゴリスムは与えられていない。この戦略については,さらに調査する必要がある。
単一の名前空間だけを扱うDTDにおいても,巨大なもの,例えばXHTML Modularization, TEI, Doc Bookは幾つかのモジュールに分割されている。小さなモジュールは, 分かりやすくなるというだけではなく,モジュールを取捨選択して組み合わせることによって多様な要求に応じられるという利点をもつ。
しかし,このモジュール分割を行うためには,あるモジュールで記述した内容を別のモジュールから変更することが必要になる。次に,その例を示す。
現在のこの標準情報(TR)は,これらの要求を満たしてなく,今後の課題として残されている。現在の規定で可能なのは,次の二つである。
解決方法の候補として次がある。これらについては,RELAX Namespaceと併行して検討する。
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
この標準情報(TR)の原案を作成した(財)日本規格協会情報技術標準化研究センター(INSTAC)の高速Webにおける標準化に関する調査研究委員会, 作業グループ(WG3)及びXML特別作業グループ(XML-SWG)の委員構成を, その順に次に示す。
氏名 | 所属 | |
---|---|---|
(委員長) | 池田 克夫 | 京都大学 |
(幹事) | 鯵坂 恒夫 | 和歌山大学 |
(幹事) | 小町 祐史 | 松下電送システム株式会社 |
(幹事) | 平山 亮 | ヒューレット・パッカード日本研究所 |
内山 光一 | 株式会社東芝 | |
久保田 靖夫 | 大日本印刷株式会社 | |
黒川 利明 | 株式会社CSK | |
斎藤 伸雄 | 凸版印刷株式会社 | |
澤田 位 | 財団法人日本規格協会 | |
八田 勲 | 通商産業省工業技術院標準部 | |
二本松 勝 | 株式会社日立製作所 | |
氏兼 裕之 | 通商産業省機械情報産業局 | |
古瀬 幸広 | 立教大学 | |
松本 充司 | 早稲田大学 | |
柳町 昭夫 | 株式会社NHKアイテック | |
(事務局) | 山中 正幸 | 財団法人日本規格協会 |
氏名 | 所属 | |
---|---|---|
(主査) | 小町 祐史 | 松下電送システム株式会社 |
(幹事) | 内山 光一 | 株式会社東芝 |
奥井 康弘 | 株式会社日本ユニテック | |
上村 圭介 | 国際大学グローバルコミュニケーションセンター | |
北野 敬介 | 日本サン・マイクロシステムズ株式会社 | |
黒川 利明 | 株式会社CSK | |
郡山 龍 | 株式会社アプリックス | |
澤田 位 | 財団法人日本規格協会 | |
湯沢 広吉 | 通商産業省機械情報産業局 | |
内藤 広志 | 大阪工業大学 | |
乃木 篤 | 株式会社CSK | |
田川 淳 | 通商産業省工業技術院標準部 | |
オブザーバ | 浅利 千鶴 | 浅利会計事務所 |
オブザーバ | 山東 滋 | 株式会社日立製作所 |
オブザーバ | 稲垣 博人 | 日本電信電話株式会社 |
オブザーバ | 荻原 崇弘 | 通商産業省機械情報産業局 |
(事務局) | 山中 正幸 | 財団法人日本規格協会 |
氏名 | 所属 | |
---|---|---|
(主査) | 村田 真 | 富士ゼロックス情報システム株式会社 |
内山 光一 | 株式会社東芝 | |
小町 祐史 | 松下電送システム株式会社 | |
檜山 正幸 | 檜山オフィス | |
奥井 康弘 | 株式会社日本ユニテック | |
高橋 亨 | 株式会社日立製作所 | |
川俣 晶 | 株式会社ピーデー | |
上村 圭介 | 国際大学グローバルコミュニケーションセンター | |
今郷 詔 | 株式会社リコー |
この標準情報(TR)の作成に際しては, 原案作成委員会委員以外の次の方々から大きな貢献をいただいた。
氏名 | 所属 | |
---|---|---|
山本 春声 | ||
浅海 智晴 | じゃばじゃば主宰 | |
川口 耕介 | 有限会社Swift | |
小崎 資広 | 松下AVCマルチメディアソフト株式会社 | |
難波 亮丞 | ||
米倉 宏治 | 日本電気株式会社 | |
三木 大知 | ||
Eve L. Maler | Sun Microsystems, Inc. |
RELAXは,XMLベースの言語を記述するための規定である。例えば,XHTML 1.0 は, XMLベースの言語なので,RELAXで記述することができる。RELAXによる記述をRELAX文法という。
従来用いられてきたDTD(Document Type Definition)と比べて,RELAXは次の特徴を備えている。
RELAXプロセサによって,XML文書をRELAX文法と照合することができる。 RELAXプロセサへの入力は,XML文書とRELAX文法である。正確には,RELAXプロセサは, XML文書及びRELAX文法を直接扱うのではなく,XMLプロセサがこれらを処理したあとの出力を扱う。
XML文書がこのRELAX文法に照らして合法かどうかを, RELAXプロセサは報告する。RELAXプロセサは,他にも診断メッセージを出すことがある。RELAXプロセサには,これ以外の出力はない。
RELAXは,RELAX Core及びRELAX Namespaceの二つから成る。RELAX Coreは,一つの名前空間にある要素及びその属性を扱う。RELAX Coreは,XML Schema Part 2のデータ型を採用している。RELAX Namespaceは,RELAX Coreで書かれた複数のモジュールを組み合わせ,複数の名前空間を扱う。
ここでは,パラメタ実体を使わない範囲のDTDをRELAXにどう移行するかを示す。
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>
次に,この例に含まれる構文を説明する。
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である。
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>
XMLでいう要素型宣言(<!ELEMENT ...>)は, elementRule
要素によって表現される。
elementRule
のrole
属性は,要素型の名前を指定する。
elementRule
は,interface
の後に幾つでも書くことができる。
<elementRule role="element-type-name"> ...hedge model... </elementRule>
elementRule
要素は,生け垣モデルをもつことができる。生け垣とは,要素(子孫要素も含む)及び文字データの並びのことである。生け垣モデルとは,どんな生け垣が許されるかを表す制約条件である。
生け垣モデルには,要素生け垣モデル,データ型参照,混在生け垣モデルがある。
要素生け垣モデルは,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
の内容としては何も許されないことを示している。
elementRule
のtype
属性によって,データ型を参照する内容モデルを書くことができる。文書中に書かれた文字列は,参照されたデータ型と照合される。指定できるのは,XML Schema Part 2で導入されたデータ型の名前,又はRELAXが独自に導入したデータ型の名前である。
type
を用いたelementRule
の例を, 次に示す。
<elementRule role="bar" type="integer"/>
このelementRule
は,bar
要素の内容は整数を表現する文字列であることを示している。
<bar>10</bar>
前後に空白を挿入することはできない。すなわち,次の例は許されない。
<bar> 10 </bar>
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/>Makoto</bar>
XMLの(#PCDATA | foo1 | foo2)*を表現するには,次のとおりに書く。
<elementRule role="bar"> <mixed> <choice occurs="*"> <ref label="foo1"/> <ref label="foo2"/> </choice> </mixed> </elementRule>
生け垣モデル(#PCDATA)を表現するには,二つの方法がある。一つは,データ型string
をtype
属性で指定する方法である。もう一つは,mixed
要素の中に,空のラベル列だけとマッチする要素生け垣モデルを記述する方法である。次にその例を示す。
<elementRule role="bar" type="string"/>
<elementRule role="bar"> <mixed> <empty/> </mixed> </elementRule>
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"/>