STEP 2: XML DTDからの移行(パラメタ実体あり)

$Id: step2.html 1.21 2000/02/21 13:13:36 murata Exp $

text by 村田 真

html by 難波 亮丞


STEP 2では,同じことを何度も繰り返して記述する代わりに,一回だけ 記述しておいたものを繰り返して参照するための機構が加わります.XML にあるパラメタ実体に相当します.

1. 要素内容モデルの中で用いられるパラメタ実体

生け垣モデルを一回だけ記述し,それを繰り返して参照するための機構が hedgeRule 要素です.DTD にあるパラメタ実体のうち, 内容モデルで使われるものに相当します.

1.1 概要

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 の時点では,矛盾する説明で我慢して下さい. 名前がぶつからないように使ったときの意味は明らかでしょう.

1.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を参照しており,phrasehedgeRuleで記述されています.

<hedgeRule label="phrase">
  <choice>
    <ref label="em"/>
    <ref label="strong"/>
  <choice>
</hedgeRule>

<elementRule pred="p">
  <mixed>
    <ref label="phrase" occurs="*"/>
  </mixed>
</elementRule>

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

1.4 refhedgeRuleの 順番

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>

1.5 自分自身を参照しないこと

自分自身を直接または間接に参照するような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>

1.6 emptyの用途

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の構造を変更できます.

1.7 noneの用途

同じく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の内容を変更 できます.

2. 属性リスト宣言の中で用いられるパラメタ実体

属性宣言をいくつかまとめて一回だけ記述し,それを繰り返して参照する ための機構がattList要素です.DTD にあるパラメタ実体のうち, 属性リスト宣言で使われるものに相当します

2.1 概要

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の中からも同様に可能です.

2.2 refattListの順番

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>

2.3 複数のref要素

一つの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>

2.4 自分自身を参照しないこと

hedgeRuleのときと同様に,自分自身を直接的または間接的 に参照するのはエラーです.たとえば,次の例はエラーです.

<attList pred="bar1">
  <ref pred="bar2"/>
  <attribute name="id" type="NMTOKEN"/>
</attList>

<attList pred="bar2">
  <ref pred="bar1"/>
</attList>

3. まとめ

STEP 2までで,XMLのDTDで出来ることはだいたい出来ます.ぜひ使ってみ て下さい.RELAX!

mura034@attglobal.net

Valid HTML 4.0!