element
$Id: step9.html 1.9 2000/02/21 13:16:09 murata Exp $
内容モデルはelementという要素を持つことができます。これは、単なる略 記法であり、refとelementRuleとtagに展開されます。この節では、ま ずelement要素の目的を説明し、次に機構を説明します。
RELAXはDTDの拡張であり、文法的なデータモデルを持っています。これは、 プログラミング言語やデータベースのデータモデルとは異質なものです。しか し、RELAXでプログラミング言語の変数宣言やデータベースのスキーマを 真似ることは考えておく必要があります。
プログラミング言語では、変数を宣言するときに同時にその型を宣言しま す。たとえば、次の例は変数xとyを宣言し、型としてintを指定しています。
public class Point { int x; int y; }
型がintであるという情報は、クラスPointのxに固有なものです。変数xが 別のクラスで宣言されるときは、異なる型を指定されているかも知れません。 たとえば、次の例ではxがfloat型として宣言されています。
public class Foo { float x; }
element要素は、変数名と型の指定を同時に行うための要素内容モデルです。 element要素は、必ずname属性を持ちます。また、type属性かlabel属性の どちらかを持ちます。さらに、occurs属性も持つことができます。
<element name="tag-name" type="datatype-name"/>
<element name="tag-name" label="label-name"/>
element要素を用いることによって次のようなルールが書けます。
<contentRule label="Point"> <sequence> <element name="x" type="integer"/> <element name="y" type="integer"/> </sequence> </contentRule>
変数posの型がPointクラスだとします。x=100, y=200である ようなposは次のXML文書によって表現できます。
<pos> <x>100</x> <y>200</y> </pos>
もう一つ別のクラスを考えます。さきに定義したクラスPointを参照してい ます。
public class Rectangle { Point topLeft; Point bottomRight; }
このクラスをelement要素を使ってRELAXで表現します。今度はtype属性で はなく、label属性を使います。
<contentRule label="Rectangle"> <sequence> <element name="topLeft" label="Point"/> <element name="bottomRight" label="Point"/> </sequence> </contentRule>
変数rectの型がクラスRectangleであり、x=100, y=200であるような点がtopLeftであり、x=300, y=400であるような点がbottomRightだとします。
<rect> <topLeft> <x>100</x> <y>200</y> </topLeft> <bottomRight> <x>300</x> <y>400</y> </bottomRight> </rect>
element要素は単なる構文糖衣(syntax sugar)です。内容モデル中の element要素はrefに置き換えられ、elementRuleとtagが生成され ます。
前節の一つ目のcontentRuleをもう一度示します.使用されているelement要素 はtype属性を指定しています.この例について,展開が どう行われるかを考えます.
<contentRule label="Point"> <sequence> <element name="x" type="integer"/> <element name="y" type="integer"/> </sequence> </contentRule>
二つのelement要素はそれぞれref要素によって置き換えられます.また, elementRuleとtagがそれぞれに対して生成されます.生成されるelementRule の内容モデルは,elementのtype属性で指定されたデータ型への参照です.
<contentRule label="Point"> <sequence> <ref label="Point$1"/> <ref label="Point$2"/> </sequence> </contentRule> <elementRule pred="Point$1" label="Point$1" type="integer"/> <tag pred="Point$1" name="x"/> <elementRule pred="Point$2" label="Point$2" type="integer"/> <tag pred="Point$2" name="y"/>
前節の二つ目のcontentRuleをもう一度示します.使用されているelement要素 はlabel属性を指定しています.この例について,展開が どう行われるかを考えます.
<contentRule label="Rectangle"> <sequence> <element name="topLeft" label="Point"/> <element name="bottomRight" label="Point"/> </sequence> </contentRule>
二つのelement要素はそれぞれref要素によって置き換えられます.また, elementRuleとtagがそれぞれに対して生成されます.生成されるelementRule の内容モデルは,elementのlabel属性で指定されたラベルを参照するref要素 です.
<contentRule label="Rectangle"> <sequence> <ref label="Rectangle$1"/> <ref label="Rectangle$2"/> </sequence> </contentRule> <elementRule pred="Rectangle$1" label="Rectangle$1"/> <ref label="Point"/> </elementRule> <tag pred="Rectangle$1" name="topLeft"/> <elementRule pred="Rectangle$2" label="Rectangle$2"/> <ref label="Point"/> </elementRule> <tag pred="Rectangle$2" name="bottomRight"/>
element要素がoccurs属性を持っているときは、生成されるref要素に occurs属性が付与されます。たとえば、最初のcontentRuleでelementに occurs="?"が指定されたとします。
<contentRule label="Point"> <sequence> <element name="x" type="integer" occurs="?"/> <element name="y" type="integer" occurs="?"/> </sequence> </contentRule>
展開の結果は次のようになります。
<contentRule label="Point"> <sequence> <ref label="Point$1" occurs="?"/> <ref label="Point$2" occurs="?"/> </sequence> </contentRule> <elementRule pred="Point$1" label="Point$1" type="integer"/> <tag pred="Point$1" name="x"/> <elementRule pred="Point$2" label="Point$2" type="integer"/> <tag pred="Point$2" name="y"/>
前節の内容を展開規則としてまとめておきます.
他のラベルと衝突しないラベルが自動生成され、ref要素のlabel属性で指定さ れます。もし、element要素にoccurs属性があれば、ref要素がそれを引き継ぎ ます。
他の述語名と衝突しない述語名が自動生成され、 pred属性で指定されます。label属性の値は,ref要素を生成したときに自動生成したラベルです。 このelementRuleの内容モデルは次のようにして決まります。
elementRuleを生成するときに自動生成した述語名がpred属性として指定されます。 name属性としては、元々のelement要素のname属性の値が指定されます。
STEP 9までで、RELAX Coreのほぼすべての機能を見たことになります。 モジュール化の機能をRELAX Namespaceで導入するときには、それに 対応してRELAX Coreも機能拡張しますが、それ以外の機能はRELAX Core Version 1.0には入りません。RELAX!
mura034@attglobal.net