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

$Id: step1.html 1.32 2000/03/13 12:20:29 murata Exp $

text by 村田 真

html by 難波 亮丞


Step 1は、DTDをちょっと知っている人なら、すぐに移行できる範囲の機能です.また、dtd2relaxコンバータが生成する範囲でもあります.

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/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>

以下の章では、この例で示した構文を説明していきます.

2. 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 です.

3. interface 要素

moduleの先頭はinterface要素が入 ります.一つのモジュールに二つ以上のinterface要素が存在す ることはありません.

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

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

3.1 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>

4. 要素型宣言

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

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

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

生け垣モデルには、要素生け垣モデル、データ型参照、混在生け垣モデル があります.

4.1 要素生け垣モデル

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

(1) empty要素

empty 要素は、空の内容を表します.

次のelementRuleを考えます.

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

このelementRuleは、foo要素の内容が空である ことを表しています.開始タグの直後に終了タグを置いても、空要素タグを用 いても構いません.

<foo/>
<foo></foo>

XMLのEMPTYとは異なり、開始タグと終了タグの間に空白だけを置くこ とも許されます.

<foo>  </foo>

emptyは、後述するchoicesequence(3), (4)を参照) の中で使用することができます.この ように拡張する理由は、STEP 2 で明らかになり ます.なお、XMLのEMPTYとまったく同じ機能が必要なら、STEP 3にあるデータ型emptyStringを使っ て下さい.

以下では、要素型foo, foo1, foo2は、emptyを生け垣モデルとして持つ elementRuleによって宣言されているものとみなして説明します.

(2) 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>

(3) choice要素

choice 要素は選択(XMLにある"|")を表します. choice要素の子供は要素生け垣モデルです.choiceoccurs属性を持つことが出来ます.

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>

(4) sequence要素

sequence 要素 は並び(XMLにある",")を表します. sequence要素の子供は要素生け垣モデルです. sequenceoccurs属性を持つことが出来ます.

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>

(5) none要素

none 要素 は、RELAXではじめて導入されたもので、 何ともマッチしないという生け垣モデルです.

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

このelementRuleは、barの内容としてはなにも許されないこ とを示しています.noneを導入する理由は、STEP 2 で明らかになります.

4.2 データ型参照

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

typeを用いたelementRuleの例を示します.

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

このelementRuleは、bar要素の内容は整数を 表現する文字列であることを示します.

<bar>10</bar>

前後に空白を挿入することはできません.すなわち、次の例は許されません.

<bar>
  10
</bar>

4.3 混在生け垣モデル

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/>Mako&#x74;&#x6F;</bar>

XMLの(#PCDATA | foo1| foo2)*を表現するには、次のように書きます.

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

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

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

4.属性リスト宣言

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"/>

6. まとめ

ここまで読んでいただければ、ただちにRELAXを使いはじめることが できます.不便を感じなければ、STEP 2以降の内容を読む必要はありません. ぜひ使ってみて下さい.RELAX!

mura034@attglobal.net

Valid HTML 4.0!