$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