$Id: step1.html 1.32 2000/03/13 12:20:29 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 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/2000/relaxCore">
<interface>
<export labels="doc"/>
</interface>
<elementRule pred="doc">
<sequence>
<ref label="title"/>
<ref label="para" occurs="*"/>
</sequence>
</elementRule>
<elementRule pred="para">
<mixed>
<ref label="em" occurs="*"/>
</mixed>
</elementRule>
<elementRule pred="title">
<mixed>
<ref label="em" occurs="*"/>
</mixed>
</elementRule>
<elementRule pred="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/2000/relaxCore">
...
</module>
moduleVersion 属性は、このモジュールのバージョ
ンを表します.この例では、"1.2"です.
relaxCoreVersion 属性は、RELAX Core自体のバー
ジョンを表します.現在は必ず"1.0"です.
targetNamespace 属性は、このモジュールが扱う
名前空間を指定します.この例では、""を指定しています.
RELAX Coreのための名前空間名は、http://www.xml.gr.jp/2000/relaxCore です.
interface 要素moduleの先頭はinterface要素が入
ります.一つのモジュールに二つ以上のinterface要素が存在す
ることはありません.
<module
moduleVersion="1.2"
relaxCoreVersion="1.0"
targetNamespace=""
xmlns="http://www.xml.gr.jp/2000/relaxCore">
<interface>
...
</interface>
...
</module>
export要素interface要素の中にはexport要素がいくつか
入ります.
<export labels="foo bar"/>
export 要素のlabels 属性
の値は、ルートになりうる要素型の並びです.export要素
は複数あっても構いません.
以下の二つの例は,どちらも要素型fooとbarがルートになりうることを 表しています.
<interface> <export labels="foo"/> <export labels="bar"/> </interface>
<interface> <export labels="foo bar"/> </interface>
XMLでいう要素型宣言(<!ELEMENT ...>)は、elementRule
要素によって表現されます.elementRuleのpred
属性は,要素型の名前を指定します.elementRuleは、
interfaceの後にいくつでも書くことができます.
<elementRule pred="element-type-name"> ...hedge model... </elementRule>
elemementRule要素は、生け垣モデルを持つことが
できます.生け垣とは,要素(子孫要素も含む)と文字データの並
びのことです.生け垣モデルとは,どんな生け垣が許されるかを表す制約条件
です.
生け垣モデルには、要素生け垣モデル、データ型参照、混在生け垣モデル があります.
要素生け垣モデルは,empty, ref, choice, sequence, none
要素とoccurs属性によって表現されます.要素生け垣モデルは,
子供要素の並びとして何を許容するかを表現します.また、これらの要素の間
に適当に空白を挿入することができます.
empty要素empty 要素は、空の内容を表します.
次のelementRuleを考えます.
<elementRule pred="foo"> <empty/> </elementRule>
このelementRuleは、foo要素の内容が空である
ことを表しています.開始タグの直後に終了タグを置いても、空要素タグを用
いても構いません.
<foo/>
<foo></foo>
XMLのEMPTYとは異なり、開始タグと終了タグの間に空白だけを置くこ とも許されます.
<foo> </foo>
emptyは、後述するchoiceや
sequence((3), (4)を参照) の中で使用することができます.この
ように拡張する理由は、STEP 2 で明らかになり
ます.なお、XMLのEMPTYとまったく同じ機能が必要なら、STEP 3にあるデータ型emptyStringを使っ
て下さい.
以下では、要素型foo, foo1, foo2は、emptyを生け垣モデルとして持つ
elementRuleによって宣言されているものとみなして説明します.
ref要素ref 要素 は、要素型を参照します.例えば、
<ref label="foo"/>は、fooという要素型を参照します.
次のelementRuleを考えます.
<elementRule pred="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 pred="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 pred="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 pred="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 pred="bar"> <none/> </elementRule>
このelementRuleは、barの内容としてはなにも許されないこ
とを示しています.noneを導入する理由は、STEP 2 で明らかになります.
elementRuleのtype 属性によって、
データ型を参照する内容モデルを書くことができます.文書中に書かれた文字
列は、参照されたデータ型と照合されます.指定できるのは、XML Schema
Part 2で導入されたデータ型の名前か、RELAXが独自に導入したデータ型
の名前です.データ型についてはSTEP 3で説明し
ます.
typeを用いたelementRuleの例を示します.
<elementRule pred="bar" type="integer"/>
このelementRuleは、bar要素の内容は整数を
表現する文字列であることを示します.
<bar>10</bar>
前後に空白を挿入することはできません.すなわち、次の例は許されません.
<bar> 10 </bar>
mixed 要素は、XMLにある混在生け垣モデル
(#PCDATA|a|b|...|z)* を大幅に拡張したものです.
<mixed> と </mixed> の間には、
要素生け垣モデルが書けます.要素生け垣モデルを直接書いたときは、要素の
間には空白だけが挿入できたことを思い出して下さい.mixedで
囲むことにより、空白だけではなく、どんな文字でも挿入できるようになりま
す.
たとえば、次のelementRuleを考えます.
<elementRule pred="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 pred="bar">
<mixed>
<choice occurs="*">
<ref label="foo1"/>
<ref label="foo2"/>
</choice>
</mixed>
</elementRule>
生け垣モデル(#PCDATA)を表現するには、二つの方法があります.一つは、
データ型stringをtype属性で指定する方法です.
もう一つは、mixed要素のなかに、空のラベル列だけとマッチす
る要素生け垣モデルを記述する方法です.次にその例を示します.
<elementRule pred="bar" type="string"/>
<elementRule pred="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">
次の二つの開始タグは従っていません.一つ目の例は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!
mura034@attglobal.net