第23回 実体宣言の概要と内部実体宣言 Page 2

川俣 晶
株式会社ピーデー
2004/7/9

実体宣言の定義

 実体宣言の規定は、まずentity declaration(実体宣言)という用語の定義から始まる。最初の文は以下のようになっている。

[Definition: Entities are declared thus:]

[定義:実体は、次のとおりに宣言する:]

 この文章は、非常に嫌らしい構造になっている。これは用語の定義であり、entity declaration(実体宣言)という用語を定義しているにもかかわらず、entity declaration(実体宣言)という言葉がこの文章には出てこない。Internet Explorerなら「Definition」という文字の上にマウスポインタを持っていけばentity declarationという文字がポップアップするが、紙に印刷してしまえば、その情報を見ることはできない。この問題は、日本語訳のJIS規格であるJIS X 4159ではもっと深刻になる。JIS規格は紙に印刷されたものが基準となるが、この印刷製本されたJIS規格を見て、それが実体宣言という用語の定義であることを察知することはほとんど不可能だろう。

 実体宣言の内容は、以下に記述された内容となる。

実体宣言の生成規則

 実体宣言の生成規則は以下のとおりである。

Entity Declaration
[70]    EntityDecl    ::=    GEDecl | PEDecl
[71]    GEDecl    ::=    '<!ENTITY' S Name S EntityDef S? '>'
[72]    PEDecl    ::=    '<!ENTITY' S '%' S Name S PEDef S? '>'
[73]    EntityDef    ::=    EntityValue| (ExternalID NDataDecl?)
[74]    PEDef    ::=    EntityValue | ExternalID

 まず、実体宣言そのものに対応する生成規則[70] EntityDeclを見てみよう。これは、マーク付け宣言に対応する生成規則[29] markupdeclより参照されている。これは以下のような内容であった。

[29]    markupdecl    ::=    elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment

 この生成規則から、実体宣言はelementdecl(要素型宣言)やAttlistDecl(属性リスト宣言)などと並べて、同じ場所に記述できることが分かる。つまりDTDに記述する。

 さて、生成規則[70] EntityDeclの中身を見てみよう。内容は、GEDeclとPEDeclのいずれかということになっている。これらは、すぐ次に記述されている生成規則[71] GEDecl生成規則[72] PEDeclなので、次にこの2つについて見てみよう。

 生成規則[71] GEDeclと生成規則[72] PEDeclは、いずれも'<!ENTITY'という文字列で始まる構文を宣言している。しかし、内容は同一ではない。それぞれ、文書内容で参照する一般実体宣言、DTD中で参照するパラメタ実体宣言に対応しているためである。両者の相違は2点ある。まず、生成規則[72] PEDeclにのみ「%」記号を記述する構文が見られることである。「%」記号を使うことで、パラメタ実体を表現するのが、パラメタ実体参照でも見られる特徴である。もう1つは、定義の内容を示す生成規則が、生成規則[73] EntityDef生成規則[74] PEDefかという相違である。この2つの生成規則は、この直後に出てくるので続けて読んでみよう。

 生成規則[73] EntityDefと生成規則[74] PEDefは、よく似ている。相違点は、生成規則[73] EntityDefでのみ生成規則[76] NDataDeclを参照していることだけなので、まとめて説明しよう。この内容は、生成規則[9] EntityValue生成規則[75] ExternalID(EntityDefの場合は(ExternalID NDataDecl?))のいずれかということを示している。生成規則[9] EntityValueは、以下のような内容であった。

[9]    EntityValue    ::=    '"' ([^%&"] | PEReference | Reference)* '"' | "'" ([^%&'] | PEReference | Reference)* "'"

 つまり、「%&」という記号を含まない文字か、パラメタ実体参照、実体参照の0回以上の繰り返しである。それを、「"」か「'」でくくるというのが、この生成規則である。実体の内容をテキストとして宣言する場合は、この構文を使えばよい。例えば「3.4 Conditional Sections(3.4 条件付きセクション)」の最後のサンプルに含まれる以下のような行は、まさに生成規則[9] EntityValueを使ったパラメタ実体の宣言の例である。

<!ENTITY % final 'IGNORE' >

 ちなみに、'IGNORE'という部分が生成規則[9] EntityValueに対応する。

 次に生成規則ExternalIDは生成規則[75] ExternalIDに当たる。これは、次回解説予定の「4.2.2 External Entities(4.2.2 外部実体)」に出てくるので、ここでは詳しく説明しない。外部実体の内容を示す構文だと思えばよいだろう。例えば外部に存在する解析対象実体を参照するために使う。

 さて、最後に残された問題は、生成規則[73] EntityDefにのみ含まれ、省略可能な生成規則NDataDeclである。これは生成規則[76] NDataDeclに当たり、これは次回解説予定の「4.2.2 External Entities(4.2.2 外部実体)」に出てくるので、ここでは詳しく説明しない。しかし、どうして、生成規則[73] EntityDefにのみ含まれ、生成規則[74] PEDefには含まれないか、その理由についてはここで説明しておく必要があるだろう。

 パラメタ実体は、DTDの内部に限って使用される実体であり、DTDを構成するテキストの一部を実体参照を通して扱えるようにするものであるから、DTDの一部が実体の内容と置き換えられる。そこから明らかであるように、DTDの構文に適合したテキスト以外のものを、パラメタ実体参照で使うことはできない。一方、生成規則[76] NDataDeclとは、解析対象外実体を示すものである。つまり、記法を通じて参照される。記法は通常XMLの構文では表現されないものを扱うために使われるものなので、DTDの一部を扱うには適さない。仮にパラメタ実体を記法を用いて宣言可能であったとしても、それを使うことはできない。たとえDTDの一部となるテキストを記述したデータであっても、記法を使って参照しているというだけで、必ずエラーになってしまうからである。

実体宣言の規定

 次に、いくつかの規定の文章が続く。

The Name identifies the entity in an entity reference or, in the case of an unparsed entity, in the value of an ENTITY or ENTITIES attribute. If the same entity is declared more than once, the first declaration encountered is binding; at user option, an XML processor MAY issue a warning if entities are declared multiple times.
Nameは、実体参照において実体を特定し、解析対象外実体ならば、ENTITY型またはENTITIES型の属性値において、実体を特定する。同一の実体が1回以上宣言されれば、最初の宣言を用い、利用者の任意選択によっては、複数回宣言される実体に関し、XMLプロセサは、警告を出してもよい。

 冒頭の文章は、生成規則[5] Nameで示される名前について2つのことをいっている。それぞれ解析対象外実体ではないときと、そうであるときの話である。解析対象外実体ではない場合は、実体参照で実体を特定する名前となる。実体参照については前回「実体参照の定義」で説明したものである。解析対象外実体の場合は、ENTITY型またはENTITIES型の属性値に記述する名前とする。この場合は、実体参照の構文は使用されず、ENTITY型またはENTITIES型の属性値によってのみ指定できる。

 次の文章は、2つのことを述べている。まず、同一の実体とは同じ名前を持つ実体のことをいう。そのような実体が宣言されても、エラーにはならず、最初に宣言したものを用いるとしている。これは「2.8 Prolog and Document Type Declaration(2.8 前書きおよび文書型宣言)」の以下の文章を思い出すことで、その意味がよく分かると思う。

外部サブセットおよび内部サブセットの両方を使用するときは、内部サブセットが外部サブセットより先に出現したと見なす。これは、内部サブセットの実体および属性リスト宣言が、外部サブセットの実体および属性リスト宣言に優先するという効果をもたらす。

 つまり、外部サブセットと内部サブセットの両方があるとき、内部サブセットの方が先にあると見なされる。そして、実体の宣言が外部サブセットと内部サブセットの両方に存在する場合、内部サブセットの方が先と見なされるため、最初に宣言されたものを用いるという規定により、内部サブセットのものが使われる。これにより、通常は書き換えることができない既成の外部サブセットで宣言された実体宣言を、内部サブセットで上書きすることができるわけである。

 文章の内容はまだ続く。文章後半は、利用者の任意選択(at user option)によって選択してよい機能について記述している。もし利用者が選択した場合は、同一の実体を1回を超えて宣言した場合、そのことを警告するようにしてもよいのである。外部サブセットを内部サブセットで上書きするような使い方を除けば、同じ名前の実体を複数宣言するのは単なる書き間違いの可能性が高いので、検出することは有益だろう。しかし、常に警告を発するように規定することは、本来の使い方から見て不適切になるので、任意選択としたものだろう。

 以上で「4.2 Entity Declarations(4.2 実体宣言)」に直接続く文章は終わり、次ページから内部実体の宣言に関する規定である「4.2.1 Internal Entities(4.2.1 内部実体)」に入っていく。(次ページに続く)

2/3

 Index
やさしく読む「XML 1.0勧告」 第23回
実体宣言の概要と内部実体宣言
  Page 1
実体宣言の概要
実体宣言にまつわる問題点
Page 2
実体宣言の定義
実体宣言の生成規則
実体宣言の規定
  Page 3
内部実体の定義
内部実体宣言の例


連載 やさしく読む「XML 1.0勧告」


XML & SOA フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

HTML5+UX 記事ランキング

本日月間