$Id: step2.html 1.21 2000/02/21 13:13:36 murata Exp $
STEP 2では,同じことを何度も繰り返して記述する代わりに,一回だけ 記述しておいたものを繰り返して参照するための機構が加わります.XML にあるパラメタ実体に相当します.
生け垣モデルを一回だけ記述し,それを繰り返して参照するための機構が
hedgeRule
要素です.DTD にあるパラメタ実体のうち,
内容モデルで使われるものに相当します.
hedgeRule
要素の構文を次に示します.foo
は
パラメタ実体の名前です.
<hedgeRule label="foo"> ...element content model... </hedgeRule>
このように定義したhedgeRule
を参照するには,
<ref label="foo"/>
と書きます.このref
要
素は,hedgeRule
の中で指定された要素生け垣モデルで置き換え
られます.
以下の例では,要素型doc
のための
elementRule
の生け垣モデルからhedgeRule
を参照し
ています.このelementRuleは,STEP 1の先頭に
あるモジュールにあったものを書き換えて,title
以外の部分を
hedgeRule
で記述したものです.
<hedgeRule label="doc.body"> <ref label="para" occurs="*"/> </hedgeRule> <elementRule pred="doc"> <sequence> <ref label="title"/> <ref label="doc.body"/> </sequence> </elementRule>
doc.body
への参照は次のように展開されます.
<elementRule pred="doc"> <sequence> <ref label="title"/> <ref label="para" occurs="*"/> </sequence> </elementRule>
この例では,elementRule
の中からhedgeRule
を参照しましたが,hedgeRule
の中からも同様に可能です.
なお,STEP 1では,ref
要素を
要素型への参照であると説明しました.ここでは,パラメタ実体への参照であ
ると説明しています.STEP 2 の時点では,矛盾する説明で我慢して下さい.
名前がぶつからないように使ったときの意味は明らかでしょう.
hedgeRule
の中には,要素生け垣モデルだけが書けます.デー
タ型参照や混在内容モデルは許されません.たとえば,以下の二つはどれも許
されません.
<hedgeRule label="mixed.param"> <mixed> <choice occurs="*"> <ref label="em"/> <ref label="strong"/> <choice> </mixed> </hedgeRule> <hedgeRule label="string.param" type="string"/>
混在生け垣モデルについては,その子要素である要素生け垣モデルから
hedgeRuleを参照するのが普通です.その例を次に示します.混在生け垣モデ
ルはphrase
を参照しており,phrase
は
hedgeRule
で記述されています.
<hedgeRule label="phrase"> <choice> <ref label="em"/> <ref label="strong"/> <choice> </hedgeRule> <elementRule pred="p"> <mixed> <ref label="phrase" occurs="*"/> </mixed> </elementRule>
occurs
属性パラメタ実体を参照するref
要素はoccurs
属性
を持つことができますし,hedgeRule
の中に書かれる要素生け垣モ
デルもoccurs
属性を持つことができます.次の例では,両方に
occurs
属性が指定されています.
<hedgeRule label="bar"> <sequence occurs="+" > <ref label="foo1"/> <ref label="foo2"/> <sequence> </hedgeRule> <elementRule pred="foo"> <ref label="bar" occurs="*"/> </elementRule>
両方が指定されたときは,余分なchoice
要素を導入して展開
を行います.すなわち,hedgeRule
で指定された要素生け垣モデ
ルだけを子供要素とするchoice
を導入します.この
choice
要素は,ref
要素のoccurs
属
性を引き継ぎます.
上の例では,展開後の結果は次のようになります.展開のときに導入され
たchoice
要素が,ref
要素にあった
occurs="*"
を引き継いでいます.
<elementRule pred="foo"> <choice occurs="*"> <sequence occurs="+" > <ref label="foo1"/> <ref label="foo2"/> <sequence> </choice> </elementRule>
ref
とhedgeRule
の
順番DTDにあるパラメタ実体と違い,ref
で参照する前に
hedgeRule
を書く必要はありません.たとえば,次の記述はエラー
ではありません.
<elementRule pred="doc"> <sequence> <ref label="title"/> <ref label="doc.body"/> </sequence> </elementRule> <hedgeRule label="doc.body"> <ref label="para" occurs="*"/> </hedgeRule>
自分自身を直接または間接に参照するようなhedgeRule
を書
いてはいけません.次の例では,bar
のための生け垣モデルの中
でbar
を参照していますからエラーになります.
<hedgeRule label="bar"> <choice> <ref label="title"/> <ref label="bar" occurs="*"/> </choice> </hedgeRule>
次の例では,bar1
のための生け垣モデルの中で
bar2
を参照しており,bar2
のための生け垣モデル
の中でbar1
を参照しています.したがって,エラーになります.
<hedgeRule label="bar1"> <ref label="bar2" occurs="*"/> </hedgeRule> <hedgeRule label="bar2"> <choice> <ref label="title"/> <ref label="bar1"/> </choice> </hedgeRule>
STEP 1で述べたempty
は,主に
hedgeRule
の中で使います.以下に例を示します.
<hedgeRule label="frontMatter"> <empty/> </hedgeRule> <elementRule pred="section"> <sequence> <ref label="title"/> <ref label="frontMatter"/> <ref label="para" occurs="*"/> </sequence> </elementRule>
このモジュールを再利用する人は,frontMatter
の記述をカ
スタマイズすることによって,section
の構造を変更できます.
同じくStep 1で述べたnoneもhedgeRuleの中で使います.以下に,使用例を 示します.
<hedgeRule label="local-block-class"> <none/> </hedgeRule> <hedgeRule label="block-class"> <choice> <ref label="para"/> <ref label="fig"/> <ref label="local-black-class"/> </choice> </hedgeRule>
このモジュールを再利用する人は,local-block-class
の記
述をカスタマイズすることによって,block-class
の内容を変更
できます.
属性宣言をいくつかまとめて一回だけ記述し,それを繰り返して参照する ための機構がattList要素です.DTD にあるパラメタ実体のうち, 属性リスト宣言で使われるものに相当します
attList
要素の構文を下に示します.fooはパラメタ実体の名
前です.
<attList pred="foo"> ...attribute definitions... </attList>
このように定義したattList
を参照するには,属性定義の並
びの先頭に<ref pred="foo"/>
と書きます.この
ref
要素は,attList
の中で指定された属性定義の
並びで置き換えられます.
以下の例では,要素型title
のためのtag
要素
からattList
を参照しています.このtag
は,STEP
1の先頭にあるモジュールにあったものを書き直したものです.多くの要素型に共
通するrole
属性が,common.att
という
attList
に記述されています.
<attList pred="common.att"> <attribute name="role" type="NMTOKEN"/> </attList> <tag name="title"> <ref pred="common.att"/> <attribute name="number" required="true" type="integer"/> </tag>
ref
要素は次のように展開されます.
<tag name="title"> <attribute name="role" type="NMTOKEN"/> <attribute name="number" required="true" type="integer"/> </tag>
この例では,tag
の中からattList
を参照しま
したが,attList
の中からも同様に可能です.
ref
とattList
の順番ref
で参照する前にattList
を書く必要はあり
ません.たとえば,次の記述はエラーではありません.
<tag name="title"> <ref pred="common.att"/> <attribute name="number" required="true" type="integer"/> </tag> <attList pred="common.att"> <attribute name="role" type="NMTOKEN"/> </attList>
一つのtag
またはattList
の中に,複数の
ref
要素を書くことができます.以下に,一つの
attList
のなかで複数のref
要素を用いた例を示し
ます.必須の属性をcommon-req.att
にまとめ,必須ではない属性
をcommon-opt.att
にまとめています.この二つを
common.att
を記述するattList
から参照していま
す.
<attList pred="common.att"> <ref pred="common-req.att"/> <ref pred="common-opt.att"/> </attList> <attList pred="common-req.att"> <attribute name="role" type="NMTOKEN" required="true"/> </attList> <attList pred="common-opt.att"> <attribute name="id" type="NMTOKEN"/> </attList>
hedgeRule
のときと同様に,自分自身を直接的または間接的
に参照するのはエラーです.たとえば,次の例はエラーです.
<attList pred="bar1"> <ref pred="bar2"/> <attribute name="id" type="NMTOKEN"/> </attList> <attList pred="bar2"> <ref pred="bar1"/> </attList>
STEP 2までで,XMLのDTDで出来ることはだいたい出来ます.ぜひ使ってみ て下さい.RELAX!
mura034@attglobal.net