| ENGLISH | JAPANESE |
$Id: step1.sdoc 1.13 2000/08/06 08:47:44 murata Exp $
STEP 1は,DTDをちょっと知っている人なら,すぐに移行できる範囲の機能です.また,DTD2RELAXコンバータが生成する範囲でもあります.
RELAXの感じをつかむため,一つのDTDをRELAXのモジュールとして表現してみます.
まずDTDを示します.title要素のnumber属性は整数だけに制限したいのですが,DTDでは出来ません.
<!ELEMENT doc (title, para*)> <!ELEMENT para (#PCDATA | em)*> <!ELEMENT title (#PCDATA | em)*> <!ELEMENT em (#PCDATA)> <!ATTLIST para class NMTOKEN #IMPLIED > <!ATTLIST title class NMTOKEN #IMPLIED number CDATA #REQUIRED >
つぎに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="class" type="NMTOKEN"/>
</tag>
<tag name="title">
<attribute name="class" type="NMTOKEN"/>
<attribute name="number" required="true" type="integer"/>
</tag>
<tag name="em"/>
</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>
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>
elemementRule要素は,生け垣モデルを持つことができます.生け垣とは,要素(子孫要素も含む)と文字データの並びのことです.生け垣モデルとは,どんな生け垣が許されるかを表す制約条件です.
生け垣モデルには,要素生け垣モデル,データ型参照,混在生け垣モデルがあります.
要素生け垣モデルは,empty, ref, choice, sequence, none要素とoccurs属性によって表現されます.要素生け垣モデルは,子供要素の並びとして何を許容するかを表現します.また,これらの要素の間に適当に空白を挿入することができます.
empty要素empty 要素は,空の内容を表します.
次のelementRuleを考えます.
<elementRule role="foo"> <empty/> </elementRule>
このelementRuleは,foo要素の内容が空であることを表しています.開始タグの直後に終了タグを置いても,空要素タグを用いても構いません.
<foo/>
<foo></foo>
XMLのEMPTYとは異なり,開始タグと終了タグの間に空白だけを置くことも許されます.
<foo> </foo>
emptyは,後述するchoiceやsequenceの中で使用することができます.このように拡張する理由は,STEP 2で明らかになります.なお,XMLのEMPTYとまったく同じ機能が必要なら,STEP 3にあるデータ型emptyStringを使って下さい.
以下では,要素型foo, foo1, foo2は,emptyを生け垣モデルとして持つelementRuleによって宣言されているものとみなして説明します.
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>
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>
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>
none要素none 要素は,RELAXではじめて導入されたもので,何ともマッチしないという生け垣モデルです.
<elementRule role="bar"> <none/> </elementRule>
このelementRuleは,barの内容としてはなにも許されないことを示しています.noneを導入する理由は,STEP 2で明らかになります.
elementRuleのtype 属性によって,データ型を参照する内容モデルを書くことができます.文書中に書かれた文字列は,参照されたデータ型と照合されます.指定できるのは,XML Schema Part 2で導入されたデータ型の名前か,RELAXが独自に導入したデータ型の名前です.データ型についてはSTEP 3で説明します.
typeを用いたelementRuleの例を示します.
<elementRule role="bar" type="integer"/>
このelementRuleは,bar要素の内容は整数を表現する文字列であることを示します.
<bar>10</bar>
前後に空白を挿入することはできません.すなわち,次の例は許されません.
<bar> 10 </bar>
mixed 要素は,XMLにある混在生け垣モデル(#PCDATA|a|b|...|z)*を大幅に拡張したものです.
<mixed>と</mixed>の間には,要素生け垣モデルが書けます.要素生け垣モデルを直接書いたときは,要素の間には空白だけが挿入できたことを思い出して下さい.mixedで囲むことにより,空白だけではなく,どんな文字でも挿入できるようになります.
XMLの(#PCDATA | foo1| foo2)*を表現するには,次のように書きます.
<elementRule role="bar">
<mixed>
<choice occurs="*">
<ref label="foo1"/>
<ref label="foo2"/>
</choice>
</mixed>
</elementRule>
このmixed要素に含まれるchoice要素は,foo1とfoo2の0個以上の繰り返しとマッチします.mixedの効果により,これらの要素の間に任意の文字が許されます.したがって,XMLの混在内容モデル(#PCDATA | foo1|
foo2)*と等価になります.
生け垣モデル(#PCDATA)を表現するには,二つの方法があります.一つは,データ型stringをtype属性で指定する方法です.もう一つは,mixed要素のなかに,空のラベル列だけとマッチする要素生け垣モデルを記述する方法です.次にその例を示します.
<elementRule role="bar" type="string"/>
<elementRule role="bar">
<mixed>
<empty/>
</mixed>
</elementRule>
より進んだ例として,次のelementRuleを考えます.
<elementRule role="bar">
<mixed>
<sequence>
<ref label="foo1"/>
<ref label="foo2"/>
</sequence>
</mixed>
</elementRule>
<foo1/>と<foo2/>の並びは,mixedの中のsequence要素にマッチします.したがって,次の例はこのelementRuleにより許されています.
<bar>Murata<foo1/>Makoto<foo2/>IUJ</bar>
次の例のようにCDATAセクションや文字参照が現れても構いません.
<bar><![CDATA[Murata]]><foo1/>Makoto<foo2/>IUJ</bar>
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">
次の二つの開始タグは従っていません.一つ目の例はage属性を省いていますし,二つ目の例は値が整数ではありません.
<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"/>
ここまで読んでいただければ,ただちにRELAXを使いはじめることができます.不便を感じなければ,STEP 2以降の内容を読む必要はありません.ぜひ使ってみて下さい.RELAX!