D. DTDモジュールの構築

XHTMLモジュールは,DTD素片として実装される。これらの素片が定義モジュール及び拡張モジュールをもつDTDの開発で記述される固有の方法で集められると,結果としてDTDは, 完全な文書型で表示される。そのため,文書型のインスタンスの妥当性検証に,この表示を使用することができる。

素片の定義に使用される規則が, これらの素片を意味のあるDTDに結合するための鍵となる。附属書D.は, これらの規則を定義する。これらの規則に従う場合,DTD作成者は,モジュールが他のXHTML互換モジュールと整合することを確信できる。

これらの規則に適合するモジュールは,XHTMLファミリモジュールと呼ばれるため,XHTMLファミリモジュール適合性で定義された適合性要件も満たす必要がある。

D.1.パラメタ実体の命名

この規定は,パラメタ自体を七つのカテゴリに分類し,次の接尾辞を使用してそれらに一貫した名前を付ける。

.mod
パラメタ実体がDTDモジュール(要素の集合,属性の集合,パラメタ実体の集合など)を表示するために使用される場合は,接尾辞.modを使用する。この規定では,各モジュールはアトミックな単位であり,分離ファイル実体として表示されてもよい。
.module
パラメタ実体を使用して,条件付き節キーワードであるINCLUDE又はIGNOREのいずれかを含むことによって,DTDモジュールの取込みを制御する場合は,接尾辞.moduleを使用する。
.qname
パラメタ実体を使用して,要素の修飾名を表示する場合は,接尾辞.qnameを使用する。修飾名の詳細な情報については, モジュールの名前空間の定義を参照されたい。
.content
パラメタ実体を使用して,要素型の内容モデルを表示する場合は,接尾辞.contentを使用する。
.class
パラメタ実体を使用して,同じクラスの要素を表示する場合は,接尾辞.classを使用する。
.mix
パラメタ実体を使用して,別のクラスの要素型の集合を表示する場合は,接尾辞.mixを使用する。
.attrib
パラメタ実を使用して,ATTLIST宣言内の一つ以上の完全属性規定を表示するトークンのグループを表示する場合は,接尾辞.attribを使用する。

例えば,HTML 4では,%block;パラメタ実体は,ブロックレベル要素である要素型の異種集合を表示するために定義される。この規定では,その結果として生じるパラメタ実体は%Block.mix;とする。

ここで定義されたクラスのパラメタ実体を定義する際,モジュールは,一意の接頭辞を使用することによって,実体の名前を範囲付けするのが望ましい。例えば,モジュールmymoduleの要素myelementの内容モデルは,MYMODULE.myelement.contentと命名できる。その他の方式も可能である。使用される方式にかかわらず,モジュールの作成者は,他のパラメタ実体と衝突しないように定義したパラメタ実体を一意に命名し,それによって,モジュールのインタフェース方法がその利用者に明らかになるようにするのが望ましい。

D.2. モジュールの名前空間の定義

XHTMLでは,モジュールで宣言される要素及び属性は,定義されたXML名前空間[XMLNAMES]内に存在することが必須である。この名前空間は, 任意のURIで識別される。XHTMLでは,モジュールがXML DTDを使用して実装される際には,モジュールが特別な方法で名前空間を宣言することを必須とする。これは,文書の解析及び妥当性検証のときに,名前空間接頭辞を使用したり,モジュールからの要素及び属性を識別するために使用される接頭辞の選択を可能とすることを目的としている。

内容開発者が混成文書型をベースとした文書を開発したい場合は,XHTML名前空間に属する要素,その他の名前空間に属する要素,又はその両方に属する要素で,XML名前空間接頭辞の使用を選択してもよい。これらの文書がXHTMLに適合し,かつ非名前空間認識ツールと下位互換性があることを確実にするために,W3Cは,内容開発者がXHTML名前空間に属する要素でXML名前空間接頭辞を使用しないことを推奨する。内容開発者が,名前空間認識プロセサがその内容を処理することに関心がある場合は,W3Cは,さらに,XML名前空間デフォルト機構に依存するのではなく,XHTML名前空間以外の名前空間の要素をXML名前空間接頭辞を使用して指定することを推奨する。

XHTMLに適合する各モジュールがXML DTDとして実装される場合は,デフォルトXML名前空間接頭辞,文書インスタンス内でこの接頭辞を変更するためのメソッド,及び接頭辞の処理を始めるマーク付けセクションの定義が必須となる。

複数のモジュールが関連する場合は,それらが同じ名前空間の一部であることが合法であり,望ましい。例えば,すべてのXHTMLモジュールは, 同じ名前空間の一部となる。

D.2.1. 修飾名サブモジュール

最初に,修飾名サブモジュールを定義する必要がある。サブモジュールとは,単なるファイル実体であり,適切な点で完全DTDに組み込むことができるように分離されているものをいう。修飾名サブモジュールは,次の手順を使用して構築される。この手順では,文字列MODULEは,新しいモジュールの適切な文字列に置換される。

  1. パラメタ実体MODULE.prefixedを定義する。これは,モジュール内の要素がXML名前空間の接頭辞がついた名前とともに使用されているかどうかを知らせるものとする。このパラメタ実体のデフォルト値は,"%NS.prefixed;"であるのが望ましい。NS.prefixedパラメタ実体は,デフォルトの場合にIGNOREとなるようにXHTMLの枠組みによって定義されており,文書インスタンスでは,これを使用して,XHTMLモジュールをはじめとした含まれるすべての名前空間の接頭辞変換を実行することができる。
  2. このモジュールの名前空間識別子を含むパラメタ実体MODULE.xmlnsを定義する。
  3. パラメタ実体MODULE.prefixを定義する。このパラメタ実体は,接頭辞変換が可能な場合に,使用するデフォルトの接頭辞文字列を含む。
  4. パラメタ実体MODULE.pfxを定義する。このパラメタ実体は,接頭辞変換が可能な場合は"%MODULE.prefix;:"となり,そうでない場合は""となる。
  5. パラメタ実体MODULE.xmlns.extra.attribを定義する。このパラメタ実体は,xmlns:xlinkなど,このモジュールが参照する名前空間のすべてのXML名前空間属性の宣言を含む。%MODULE.prefixedがINCLUDEに設定される場合, この属性はxmlns:%MODULE.prefix; 宣言も含むのが望ましい。
  6. MODULE.xmlns.extra.attribとしてパラメタ実体XHTML.xmlns.extra.attribを定義する。これは,通常,文書型のドライバファイルによって上書きされるが,上書きされない場合は,この定義がデフォルトとなる。
  7. モジュールが各要素を定義する際,"MODULE.NAME.qname"という形式のパラメタ実体を生成して,その修飾名を保持する。このパラメタ実体の値は"%MODULE.pfx;NAME"でなければならない。この方法では,接頭辞を使用できる場合は解析値は"PREFIX:NAME"となり,それ以外の場合は,"NAME"となる。

    あるモジュールがそのモジュールと同じ名前空間を共有しないモジュールで定義される要素に属性を追加する場合,接頭辞%MODULE.pfxを使用するように,それらの属性を宣言する。次に例を示す。

    <ENTITY % MODULE.img.myattr.qname "%MODULE.pfx;myattr" >
    

仮の品目モジュールの修飾名サブモジュールが含まれる例を次に示す。

<!-- ...................................................................... -->
<!-- Inventory Qname Module ................................................... -->
<!-- file: inventory-qname-1.mod

     PUBLIC "-//MY COMPANY//ELEMENTS XHTML Inventory Qnames 1.0//EN"
     SYSTEM "http://www.example.com/DTDs/inventory-qname-1.mod"

     xmlns:inventory="http://www.example.com/xmlns/inventory"
     ...................................................................... -->

<!-- Declare the default value for prefixing of this module's elements -->
<!-- Note that the NS.prefixed will get overridden by the XHTML Framework or
     by a document instance. -->
<!ENTITY % NS.prefixed "IGNORE" >
<!ENTITY % Inventory.prefixed "%NS.prefixed;" >

<!-- Declare the actual namespace of this module -->
<!ENTITY % Inventory.xmlns "http://www.example.com/xmlns/inventory" >

<!-- Declare the default prefix for this module -->
<!ENTITY % Inventory.prefix "inventory" >

<!-- Declare the prefix for this module -->
<![%Inventory.prefixed;[
<!ENTITY % Inventory.pfx "%Inventory.prefix;:" >
]]>
<!ENTITY % Inventory.pfx "" >

<!-- Declare the xml namespace attribute for this module -->
<![%Inventory.prefixed;[
<!ENTITY % Inventory.xmlns.extra.attrib
    "xmlns:%Inventory.prefix;   %URI.datatype;  #FIXED  '%Inventory.xmlns;'" >
]]>
<!ENTITY % Inventory.xmlns.extra.attrib "" >

<!-- Declare the extra namespace that should be included in the XHTML
     elements -->
<!ENTITY % XHTML.xmlns.extra.attrib
    %Inventory.xmlns.extra.attrib; >

<!-- Now declare the qualified names for all of the elements in the
     module -->
<!ENTITY % Inventory.shelf.qname "%Inventory.pfx;shelf" >
<!ENTITY % Inventory.item.qname "%Inventory.pfx;item" >
<!ENTITY % Inventory.desc.qname "%Inventory.pfx;desc" >
<!ENTITY % Inventory.sku.qname "%Inventory.pfx;sku" >
<!ENTITY % Inventory.price.qname "%Inventory.pfx;price" >

D.2.2. 宣言サブモジュール

次に,"宣言サブモジュール"を一つ以上定義する必要がある。これらのファイル実体は,XML DTD要素及び属性リストの宣言を目的とする。XHTML宣言モジュールは,次の過程で構築されるのが望ましい。

  1. 宣言された各要素のATTLIST内で使用するパラメタ実体を定義する。このパラメタ実体は,%MODULE.prefixed;がINCLUDEに設定される場合は%NS.decl.attribを含み,%MODULE.prefixed;がIGNOREに設定される場合は,%NS.decl.attribに"xmlns %URI.datatype; #FIXED '%MODULE.xmlns;'"を追加したものを含むのが望ましい。
  2. モジュールのすべての要素及びすべての属性を宣言する。要素の各ATTLIST内には,前述の定義をしたパラメタ実体が含まれる。それによって,必須であるすべてのxmlns属性がモジュールの各要素で利用可能となる。
  3. あるモジュールがそのモジュールと同じ名前空間を共有しないモジュールで定義される要素を属性に追加する場合は,接頭辞%MODULE.pfxを使用するようにそれらの属性を宣言する。例を次に示す。

    <ENTITY % MODULE.img.myattr.qname "%MODULE.pfx;myattr" >
    <!ATTLIST %img.qname;
          %MODULE.img.myattr.qname;    CDATA          #IMPLIED
    >
    

    これは,画像モジュールのimg要素に属性を追加することになるが,属性の名前は,接頭辞を含む修飾名となる。その場合の接頭辞は, 文書のインスタンスに対して選択される。さらに,xmlns:MODULE_PREFIX属性をimg要素の属性リストに追加することによって,XML 名前空間認識パーサがその接頭辞に基づく名前空間の解決方法を認知することになる。

次の例は,仮の品目モジュールに対する宣言サブモジュールを示す。

<!-- ...................................................................... -->
<!-- Inventory Elements Module ................................................... -->
<!-- file: inventory-1.mod

     PUBLIC "-//MY COMPANY//ELEMENTS XHTML Inventory Elements 1.0//EN"
     SYSTEM "http://www.example.com/DTDs/inventory-1.mod"

     xmlns:inventory="http://www.example.com/xmlns/inventory"
     ...................................................................... -->

<!-- Inventory Module

     shelf
        item
       sku
       desc
       price

     This module defines a simple inventory item structure
-->

<!-- Define the global namespace attributes -->
<![%Inventory.prefixed;[
<!ENTITY % Inventory.xmlns.attrib
    "%NS.decl.attrib;"
>
]]>
<!ENTITY % Inventory.xmlns.attrib
     "xmlns %URI.datatype;  #FIXED '%Inventory.xmlns;'"
>

<!-- Define a common set of attributes for all module elements -->
<!ENTITY % Inventory.Common.attrib
         "%Inventory.xmlns.attrib;
      id               ID                   #IMPLIED
>

<!-- Define the elements and attributes of the module -->
<!ELEMENT %Inventory.shelf.qname;
     ( %Inventory.item.qname; )* >
<!ATTLIST %Inventory.shelf.qname;
     location   CDATA   #IMPLIED
     %Inventory.Common.attrib;
>
<!ELEMENT %Inventory.item.qname;
     ( %Inventory.desc.qname;, %Inventory.sku.qname;, %Inventory.price.qname;) >
<!ATTLIST %Inventory.item.qname;
     location   CDATA   #IMPLIED
     %Inventory.Common.attrib;
>

<!ELEMENT %Inventory.desc.qname; ( #PCDATA ) >
<!ATTLIST %Inventory.desc.qname;
     %Inventory.Common.attrib;
>

<!ELEMENT %Inventory.sku.qname; ( #PCDATA ) >
<!ATTLIST %Inventory.sku.qname;
     %Inventory.Common.attrib;
>

<!ELEMENT %Inventory.price.qname; ( #PCDATA ) >
<!ATTLIST %Inventory.price.qname;
     %Inventory.Common.attrib;
>

<!-- end of inventory-1.mod -->

D.2.3. 独立DTDとしてのモジュールの使用

XHTMLモジュールが独立DTDとしても使用できることが望ましい場合もある。前述の品目モジュールがその好例となる。これらの項目は,XHTML文書では埋込みが可能であることが必要であると同時に,データベースなどから抽出される自立文書として利用できることも必要である。これを達成するための方法として,最も簡単なのは,モジュールの構成要素をインスタンス化するDTDファイルを定義することである。これらのDTDの構造を次に示す。

  1. XHTMLデータ型モジュールを取り込む。修飾名モジュールがこれらのデータ型を使用する可能性があり,その場合は必ずxmlns属性のURIデータ型を使用する。
  2. モジュールの修飾名モジュールを取り込む。
  3. パラメタ実体NS.decl.attribを%MODULE.xmlns.extra.attrib;と定義する。
  4. モジュールの宣言モジュールを取り込む。

品目モジュールの取り込みの例を次に示す。

<!-- ...................................................................... -->
<!-- Inventory Elements DTD ............................................... -->
<!-- file: inventory-1.dtd

     PUBLIC "-//MY COMPANY//DTD XHTML Inventory 1.0//EN"
     SYSTEM "http://www.example.com/DTDs/inventory-1.dtd"

     xmlns:inventory="http://www.example.com/xmlns/inventory"
     ...................................................................... -->

<!-- Inventory Module

     shelf
        item
       sku
       desc
       price

     This module defines a simple inventory item structure
-->

<!-- Bring in the datatypes -->
<!ENTITY % xhtml-datatypes.mod
         PUBLIC "-//W3C//ENTITIES XHTML Datatypes 1.0//EN"
         "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-datatypes-1.mod" >
%xhtml-datatypes.mod;

<!-- Bring in the qualified names -->
<!ENTITY % Inventory-qname.mod SYSTEM "inventory-qname-1.mod" >
%Inventory-qname.mod;

<!ENTITY % NS.decl.attrib "%Inventory.xmlns.extra.attrib;">

<!ENTITY % Inventory.mod SYSTEM "inventory-1.mod" >
%Inventory.mod;

<!-- end of inventory-1.dtd -->

このDTDは,モジュールからの要素だけを使用する文書によって参照できる。

<!DOCTYPE shelf SYSTEM "inventory-1.dtd">
<shelf xmlns="http://www.example.com/xmlns/inventory">
    <item>
        <desc>
      this is a description.
    </desc>
        <sku>
      this is the price.
        </sku>
        <price>
      this is the price.
    </price>
    </item>
</shelf>

この方法によって,それ自体の名前空間内に範囲付けされた要素及び属性を定義することができる。さらに,これによって,内容開発者が要素及び属性のデフォルト接頭辞を使用することが可能となる。

<!DOCTYPE inventory:shelf SYSTEM "inventory-1.dtd" [
    <!ENTITY % Inventory.prefixed "INCLUDE">
]>
<inventory:shelf xmlns:inventory="http://www.example.com/xmlns/inventory">
    <inventory:item>
        <inventory:desc>
          this is a description.
        </inventory:desc>
        <inventory:sku>
          this is the sku.
        </inventory:sku>
        <inventory:price>
          this is the price.
        </inventory:price>
    </inventory:item>
</inventory:shelf>

最後に,文書インスタンスは,DOCTYPEヘッダ及びその内部サブセット内で再度それを宣言することによって,別のXML名前空間接頭辞を使用することができる。

<!DOCTYPE i:shelf SYSTEM "inventory-1.dtd" [
    <!ENTITY % Inventory.prefixed "INCLUDE">
    <!ENTITY % Inventory.prefix "i">
]>
<i:shelf xmlns:i="http://www.example.com/xmlns/inventory">
    <i:item>
        <i:desc>
          this is a description.
        </i:desc>
        <i:sku>
          this is the price.
        </i:sku>
        <i:price>
          this is the price.
        </i:price>
    </i:item>
</i:shelf>

D.2.4. 名前空間の特異性

ここで定義されるアプローチによって,XML及びXML名前空間に適合するマーク付け言語の定義が可能となるが,XML名前空間規定が定義する振る舞いの中には,サポートされないものも存在する。

  1. XML 名前空間により,木のいずれの点でも名前空間のxmlns属性を再宣言することができる。さらに,この再宣言が名前空間のデフォルトと接頭辞使用とを交換するのを可能にし,接頭辞の変更を可能にする。この規定で定義される方法では, これはできない。文書のインスタンスを通じて,接頭辞付けが使用される場合は,所定の名前空間は,同じ名前空間の接頭辞の使用を継続するか,又はデフォルトの範囲での使用を継続しなければならない。

  2. XML名前空間のデフォルトを使用する際,その文書のDTDに依存して,要素の名前空間をパーサに知らせるのは合法である。しかし,名前空間認識プロセサは,文書の評価の際,DTDを取り込むことが必須とされないため,内容開発者は,名前空間が変わる場合は必ず要素のXML名前空間を宣言するのが望ましい。

    ...
    <p>
       <myelement xmlns="..." />
    </p>