本家「@IT」にはない内容をエンジニアライフで技術紹介するコラム。広く議論する場になることを目指します。

第052回_EntityDecl_文字参照_参照方法

»
前回に引き続いてEntityDeclについて議論します。
今回は、文字参照と参照方法を詳しく見ていきます。

文字参照のW3Cの勧告内容

----W3C勧告----
4.1 Character and Entity References

[Definition: A character reference refers to a specific character in the ISO/IEC 10646 character set, for example one not directly accessible from available input devices.]

Character Reference

[66] CharRef ::= '&#' [0-9]+ ';'
        | '&#x' [0-9a-fA-F]+ ';' [WFC: Legal Character]

Well-formedness constraint: Legal Character
 Characters referred to using character references must match the production for Char.

If the character reference begins with "&#x", the digits and letters up to the terminating ; provide a hexadecimal representation of the character's code point in ISO/IEC 10646. If it begins just with "&#", the digits up to the terminating ; provide a decimal representation of the character's code point.
----W3C勧告----
----日本語訳----
4.1 文字参照と実体参照
[定義: 文字参照はISO/IEC 10646の文字集合にある特定の文字を参照する。
例えば、入力可能なデバイスから直接アクセスできない文字を参照する。]


文字参照

[66] CharRef ::= '&#' [0-9]+ ';'
        | '&#x' [0-9a-fA-F]+ ';' [WFC: Legal Character]

整形式性制約: 正当な文字
 文字参照を使って参照する文字は生成規則Charにマッチしなければならない。

文字参照が"&#x"で始まる場合、文字参照の終わりを示す";"までの数字と文字の羅列はISO/IEC 10646のコードポイントの16進表記を意味する。
文字参照が"&#"で始まる場合、文字参照の終わりを示す";"までの数字の羅列はISO/IEC 10646のコードポイントの10進表記を意味する。
----日本語訳----

文字参照の仕様整理

文字参照の役割
文字参照はXML上のエスケープシーケンスです。
JavaのStringクラスで\tとすればタブが表示できるのと同じです。

例えば、XMLのcontentの中では"<"はタグの開始を意味するので。
構文解析が"<"の入力を受けると字句解析を経てSYMBOL(<)を得ます。さらにその先で構文解析野中でマッチング処理をします。
そうではなくて文字列"<"を得るためには、エスケープシーケンスを使って字句解析器でWORD(<)を得る必要があります。

そのための手段が文字参照です。

生成規則
生成規則は、
 CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
です。

符号化文字集合
文字参照が示すコードポイントはISO/IEC 10646を利用します。

コードポイントの表現方法
10進数または16進数を用いることができます。
生成規則を見ればわかる通り、"&#" 10進数 ";" か "&#x" 16進数 ";"で表現します。

文字参照の出現位置
生成規則 Reference ::= EntityRef | CharRef からわかる通り、文字参照は一般実体の記載できる位置と同じです。
つまり、文書実体の内容(content)、実体の内容(EntityValue)、属性値の内容(AttValue)の中に記載できます。

実体の参照方法のW3Cの勧告内容

W3Cの勧告を順にみていきますが、表現に曖昧な部分があるため少し後の部分についても先読みします。
----W3C勧告----
[Definition: An entity reference refers to the content of a named entity.] [Definition: References to parsed general entities use ampersand (&) and semicolon (;) as delimiters.] [Definition: Parameter-entity references use percent-sign (%) and semicolon (;) as delimiters.]


Entity Reference


[67] Reference ::= EntityRef | CharRef
[68] EntityRef ::= '&' Name ';' [WFC: Entity Declared]
               [VC: Entity Declared]
               [WFC: Parsed Entity]
               [WFC: No Recursion]
[69] PEReference ::= '%' Name ';' [VC: Entity Declared]
                 [WFC: No Recursion]
                 [WFC: In DTD]


Well-formedness constraint: Entity Declared
 In a document without any DTD, a document with only an internal DTD subset which contains no parameter entity references, or a document with "standalone='yes'", for an entity reference that does not occur within the external subset or a parameter entity, the Name given in the entity reference must match that in an entity declaration that does not occur within the external subset or a parameter entity, except that well-formed documents need not declare any of the following entities: amp, lt, gt, apos, quot. The declaration of a general entity must precede any
reference to it which appears in a default value in an attribute-list declaration.


Note that non-validating processors are not obligated to to read and process entity declarations occurring in parameter entities or in the external subset; for such documents, the rule that an entity must be declared is a well-formedness constraint only if standalone='yes'.


Validity constraint: Entity Declared
 In a document with an external subset or parameter entity references with "standalone='no'", the Name given in the entity reference must match that in an entity declaration. For interoperability, valid documents should declare the entities amp, lt, gt, apos, quot, in the form specified in 4.6 Predefined Entities. The declaration of a parameter entity must precede any reference to it. Similarly, the declaration of a general entity must precede any attribute-list declaration containing a default value with a direct or indirect reference to that general entity.


Well-formedness constraint: Parsed Entity
 An entity reference must not contain the name of an unparsed entity. Unparsed entities may be referred to only in attribute values declared to be of type ENTITY or ENTITIES.


Well-formedness constraint: No Recursion
 A parsed entity must not contain a recursive reference to itself, either directly or indirectly.


Well-formedness constraint: In DTD
 Parameter-entity references must not appear outside the DTD.

----W3C勧告----
----日本語訳----
[定義: 実体参照は、名前付きの実体の内容を参照する。]
[定義: 解析対象の一般実体の参照は、アンパサンド(&)とセミコロン(;)を区切り子として使う。]

[定義: パラメータ実体の参照は、パーセント(%)とセミコロン(;)を区切り子として使う。]

実体参照

[67] Reference ::= EntityRef | CharRef
[68] EntityRef ::= '&' Name ';' [WFC: 宣言した実体]
               [VC: 宣言した実体]
               [WFC: 解析実体]
               [WFC: 再帰しない]
[69] PEReference ::= '%' Name ';' [VC: 宣言した実体]
                 [WFC: 再帰しない]
                 [WFC: DTDの中]

整形式性制約: 宣言した実体
DTDを持たない文書、パラメータ実体の参照を1つも持たない内部サブセットだけを持つ文書、スタンドアロン文書宣言がyesの文書において、
外部サブセットやパラメータ実体の中に現れない実体参照は、その実体参照のNameは外部サブセットやパラメータ実体の中に現れない実体宣言のNameにマッチしなければならない。
ただし、amp, lt, gt, aposの実体名は整形式の文書でも宣言する必要がない。 一般実体の宣言は、属性リスト宣言のデフォルト値のなかに現れるその実体に対する参照より先に宣言しなければならない。


妥当性を検証しないプロセッサは、パラメータ実体の中や外部サブセットの中に現れる実体宣言を読んだり、処理したりすることを強制されないことに注意せよ。; パラメータ実体や外部サブセットの実体宣言を読み込まなかった文書は、スタンドアロン文書宣言がyesのときだけ、宣言した実体の整形式制約を適用する。


妥当性制約: 宣言した実体

外部サブセットまたはパラメータ実体の参照を持つ文書でかつ、スタンドアロン文書宣言をnoの場合、実体参照のNameは、実体宣言で宣言したものにマッチしなければならない。相互運用性のために、妥当な文書は amp, lt, gt, aposを4.6 定義済み実体で指定した形式で宣言するべきである。パラメータ実体の宣言は、その宣言が定義するNameの参照より先に宣言しなければならない。同様に、一般実体の宣言は、直接ないし間接的にその一般実体を参照するデフォルト値を持つ属性リスト宣言より先に宣言しなければならない。


整形式性制約: 解析実体

実体参照は解析外実体の参照名を含んではいけない。解析外実体は、ENTITY型またはENTITIES型で宣言した属性値にだけ参照することができる。


整形式性制約: 再帰しない

解析実体は直接または間接的に再帰的な自己参照をしてはいけない。


妥当性制約: DTDの中

パラメータ実体の参照は、DTDの外で現れてはいけない。
----日本語訳----

----W3C勧告----
4.4 XML Processor Treatment of Entities and References
・・・
Reference in DTD
as a reference within either the internal or external subsets of the DTD, but outside of an EntityValue, AttValue, PI, Comment, SystemLiteral, PubidLiteral, or the contents of an ignored conditional section (see 3.4 Conditional Sections).
・・・


Entity Type Character
Parameter Internal General External Parsed General Unparsed
Reference in Content Not recognized Included Included if validating Forbidden Included
Reference in Attribute Value Not recognized Included in literal Forbidden Forbidden Included
Occurs as Attribute Value Not recognized Forbidden Forbidden Notify Not recognized
Reference in EntityValue Included in literal Bypassed Bypassed Error Included
Reference in DTD Included as PE Forbidden Forbidden Forbidden Forbidden
----W3C勧告----
----日本語訳----
4.4 XMLプロセッサによる実体と参照の扱い
・・・
DTDの中での参照
DTDの内部または外部サブセットの中に現れる参照として扱う。ただし、EntityValue,AttValue,PI,Comment,SystemLiteral,PubidLiteral, 条件セクションのignoreの内容(3.4 条件セクション)を除く
・・・


実体の種類 文字参照
パラメータ実体 内部一般実体 外部解析対象一般実体 解析対象外実体
内容の中での参照 認識されない インクルードされる 妥当性を検証する場合インクルードされる 許されない インクルードされる
属性値の中での参照 認識されない リテラルの中でインクルードされる 許されない 許されない インクルードされる
属性値としての名前 認識されない 許されない 許されない 通知する 認識されない
実体値の中での参照 リテラルの中でインクルードされる バイパスされる バイパスされる エラー インクルードされる
DTDの中での参照 パラメータ実体としてインクルードされる 許されない 許されない 許されない 許されない
----日本語訳----

----W3C勧告----
4.4.3 Included If Validating
When an XML processor recognizes a reference to a parsed entity, in order to validate the document,
the processor must include its replacement text. If the entity is external, and the processor is not attempting
to validate the XML document, the processor may, but need not, include the entity's replacement text.
If a non-validating processor does not include the replacement text, it must inform the application
that it recognized, but did not read, the entity.
----W3C勧告----
----日本語訳----
4.4.3 妥当性を検証時展開

XMLプロセッサが解析対象実体の参照を認識したとき、文書の妥当性を検証するために、プロセッサは置換テキストをインクルードしなければならない。 外部解析対象実体の場合で、かつ、プロセッサがXML文書の妥当性を検証しようとしない場合、置換テキストをインクルードしても良いが、インクルードする必要があるわけではない。妥当性を検証しないプロセッサが置換テキストをインクルードしない場合、外部解析対象実体を認識したが読まなかった
ことをアプリケーションに通知しなければならない。
----日本語訳----

----W3C勧告----
4.4.8 Included as PE


Just as with external parsed entities, parameter entities need only be included if validating★1.
When a parameter-entity reference is recognized in the DTD and included, its replacement text must be enlarged by the attachment of one leading and one following space (#x20) character; the intent is to constrain the replacement text of parameter entities to contain an integral number of grammatical tokens in the DTD. This behavior must not apply to parameter entity references within entity values;these are described in 4.4.5 Included in Literal.


★1 斜字で表記-リンク先は4.4.3
----W3C勧告----
----日本語訳----
4.4.8 PE展開

外部解析対象実体と同じように、パラメータ実体は4.4.3 妥当性を検証する場合インクルードすると同じ制限がある。パラメータ実体の参照がDTD内で認識され、インクルードする場合、置換テキストの先頭と末尾に#x20のスペース文字を追加しなければいけない。;これにより、DTDの中の文法トークンの必要数を含んだパラメータ実体の置換テキストを構成する。この動作は実体値の中のパラメータ実体参照には適用してはいけない。(must not);この動作についての説明は、4.4.5リテラルの中でのインクルード にて記述してある。
----日本語訳----

実体の参照方法の検討

上記のW3Cの勧告の中には"検討が必要なこと"や"問題のある表現"がありますので、確認していきます。

パラメータ実体-4.4.8の仕様検討
4.4.8が示す仕様はパラメータ実体の仕様の一部です。
W3C勧告を見ると、4.4の表が良くまとまっているのでこれを覚えれば良いように感じてしまいますが、そうではありません。
また、4.4.8は4.4.3にリンクしているのですが、その説明が誤読しやすいので解説します。

4.4.8の対象と対象範囲外
前回の仕様によって、パラメータ実体の記載位置は、
 intマークアップ宣言の宣言の間(DeclSep)、
 およびintマークアップ宣言の実体宣言の内容(EntityValue)
 DeclSepマークアップ宣言の宣言の間(DeclSep)、
 DeclSepマークアップ宣言の実体宣言の内容(EntityValue)
 およびextマークアップ宣言の各マークアップ宣言の先頭と末尾を含まない位置
 extマークアップ宣言の宣言の間(DeclSep)、
 extマークアップ宣言の実体宣言の内容(EntityValue)
 およびextマークアップ宣言の各マークアップ宣言の先頭と末尾を含まない位置
に記載できます。
一方で、4.4.8が対象としている"DTDの中での参照"で示す場所は、
 intマークアップ宣言の宣言の間(DeclSep)、
 DeclSepマークアップ宣言の宣言の間(DeclSep)、
 およびextマークアップ宣言の各マークアップ宣言の先頭と末尾を含まない位置
 extマークアップ宣言の宣言の間(DeclSep)、
 およびextマークアップ宣言の各マークアップ宣言の先頭と末尾を含まない位置
です。
また対象範囲外になるのが
 intマークアップ宣言の実体宣言の内容(EntityValue)
 DeclSepマークアップ宣言の実体宣言の内容(EntityValue)
 extマークアップ宣言の実体宣言の内容(EntityValue)
です。

4.4.8の誤読しやすい場所についての検討
4.4.8の内容で誤読しやすいのは、W3C勧告の★1の部分です。ここは斜字になっていてますが、項番号が振られていません。
そのため、斜字を無視して英文のまま読もうとすると、、
Just as with external parsed entities, parameter entities need only be included if validating
外部解析実体と同じように、妥当性検証の場合、パラメータ実体はインクルードだけされる必要がある。
と読めてしまいます。(間違っていたらすみません)
ですが、ここは斜字の部分のリンクを調べてみると 4.4.3 Included If Validating を指していますから、
Just as with external parsed entities, parameter entities need only be included if validating
外部解析対象実体と同じように、パラメータ実体は4.4.3 妥当性を検証する場合インクルードすると同じ制限がある。
# 4.4.3の内容は外部解析実体の参照がcontent中に現れたときの処理なので、
# 文頭のJust as with external parsed entitiesも納得がいきます。
と読むべきだと思います。

4.4.3 の仕様の整理
4.4.8の仕様が参照している4.4.3の仕様についてみていきます。
4.4.3の仕様は、外部解析対象実体の参照がcontent中に現れたときの処理です。
4.4.3の混乱しやすいところは、W3Cの勧告が示す表と内容が一致していないところです。
まず、4.4の表としては、content中で外部解析対象実体の参照を認識したときの仕様を示しています。
一方で、4.4.3の内容は次のように、内部解析対象実体の参照についても言及しています。 整理すると、

◆妥当性を検証しないプロセッサ
内部解析対象実体の参照:置換テキストをインクルードする
外部解析対象実体の参照:置換テキストをインクルードする
または、インクルードしない場合は、読み込まなかった旨をアプリケーションに伝える
◆妥当性を検証するプロセッサ
内部解析対象実体の参照:置換テキストをインクルードする
外部解析対象実体の参照:置換テキストをインクルードする

内部解析実体の参照の取り扱いにまで言及していますが、外部解析対象実体だけにすると、

◆妥当性を検証しないプロセッサ
外部解析対象実体の参照:置換テキストをインクルードする
            または、インクルードしない場合は、読み込まなかった旨をアプリケーションに伝える
◆妥当性を検証するプロセッサ
外部解析対象実体の参照:置換テキストをインクルードする
が4.4.3の仕様です。

(4.4.8の)まとめ
4.4.8の仕様は4.4.3と同じような仕様だといっているわけですから、
 intマークアップ宣言の宣言の間(DeclSep)、
 DeclSepマークアップ宣言の宣言の間(DeclSep)、
 およびextマークアップ宣言の各マークアップ宣言の先頭と末尾を含まない位置
 extマークアップ宣言の宣言の間(DeclSep)、
 およびextマークアップ宣言の各マークアップ宣言の先頭と末尾を含まない位置
に現れたとき、
◆妥当性を検証しないプロセッサ
パラメータ実体の参照:置換テキストを前後に#x20を追加してからインクルードする
           または、インクルードしない場合は、読み込まなかった旨をアプリケーションに伝える
◆妥当性を検証するプロセッサ
パラメータ実体の参照:置換テキストを前後に#x20を追加してからインクルードする


 intマークアップ宣言の実体宣言の内容(EntityValue)
 DeclSepマークアップ宣言の実体宣言の内容(EntityValue)
 extマークアップ宣言の実体宣言の内容(EntityValue)
に現れたとき、
◆妥当性を検証しないプロセッサ

パラメータ実体の参照:置換テキストをインクルードする
           または、インクルードしない場合は、読み込まなかった旨をアプリケーションに伝える
◆妥当性を検証するプロセッサ
パラメータ実体の参照:置換テキストをインクルードする


と読むことができます。

適合性に沿った処理
39回で述べたように5.適合性 に妥当性を検証しないプロセッサのパラメータ実体の参照の処理について書いてありますから、整理してみます。


適合性による、妥当性を検証しないプロセッサの仕様

妥当性を検証しないプロセッサは
 整形式であるかを確認する
 内部サブセットを読みDTDを構築する
 文書実体を読む
ことが要件になるので
 外部サブセットを読まなくてよい
 妥当性を検証しなくてよい
ということが判ります。 処理パターンは、パラメータ実体の参照のインクルードをするかしないかで2つのパターンになります。
◆パラメータ実体の参照をインクルードする場合
要素宣言 :DTDを構築する
実体宣言 :DTDを構築する
属性リスト宣言:DTDを構築する
記法宣言 :DTDを構築する
パラメータ実体の参照を展開するとき:置換テキストとしてインクルードする
インクルードした内容を再度構文解析して、各宣言からDTDを構築する
◆パラメータ実体の参照をインクルードしない場合
スタンドアロン文書宣言がyesの場合
要素宣言 :DTDを構築する
実体宣言 :DTDを構築する
属性リスト宣言:DTDを構築する
記法宣言 :DTDを構築する
パラメータ実体の参照を展開するとき:アプリケーションに無視したことを伝える。
スタンドアロン文書宣言がnoの場合
読み飛ばしフラグをfalseで初期化する。
要素宣言 :DTDを構築する
実体宣言 :読み飛ばしフラグがfalseなら、DTDを構築する。読み飛ばしフラグがtrueなら、DTDを構築しない。
属性リスト宣言:読み飛ばしフラグがfalseなら、DTDを構築する。読み飛ばしフラグがtrueなら、DTDを構築しない。
記法宣言 :DTDを構築する
パラメータ実体の参照を展開するとき:アプリケーションに無視したことを伝える。
読み飛ばしのときに、読み飛ばしフラグをtrueにする。

4.1のNoteの段落の判り難さ
この部分は
 妥当性を検証しないプロセッサは、
  パラメータ実体の中に現れる実体宣言を読んだり処理したりすることを強制されない
  外部サブセットの中に現れる実体宣言を読んだり処理したりすることを強制されない
と言っています。
ただし、原文の not obligated to の部分は斜字になっていて、リンクを辿ると、4.4.3 Included If Validating
を指していますから、正確ではないことが判ります。
この説明の意図は、
 妥当性を検証しないプロセッサは、
  DTDの中に現れるパラメータ実体の参照は、インクルードしても、インクルードせずにアプリケーションへの通知だけしても良いので、
   インクルードする場合、
    パラメータ実体の置換テキスト内の内容を構文解析する
   インクルードしない場合
    パラメータ実体の参照を無視したことをアプリケーションに通知する
  また、外部サブセットを読まなくても良いので
   外部サブセットを読む場合
    各宣言を処理する
   外部サブセットを読まない場合
    各宣言を処理しない
となります。


よって注意書きの論旨は、
 妥当性を検証しないプロセッサはXML文書の一部を読み飛ばした可能性があるので、
  DTDが記述したとおりに構築できないかもしれない。
  そのため、読み飛ばした可能性のあるDTDを元に整形式性制約を適用してはいけない
という点と、
 スタンドアロン文書宣言がyesならば、DTDは記述したとおりに構築できたとして良い。
 もし、DTDが記述したとおりに構築できていないならば、それはスタンドアロン文書宣言の指定ミスである。
 そのため、読み飛ばした可能性があったとしてもスタンドアロン文書宣言がyesならば、整形式性制約を適用する
という点です。

「DTDが無い」の示していることを推測する
46回で宿題にしていた「DTDが無い」の判定方法について推測できるので検討します。
46回で述べたように内部サブセットや外部サブセットの中のマークアップが空かどうかを考慮にいれてパターンを検証すると次のようになります。 表1.
No. DOCTYPE宣言 内部サブセット 外部サブセット 読み飛ばし DTD
PE
―――――――――――――――――――――――――――――――――
A -- -- -- 無(一切無い)
B -- 無(一切無い)
C -- 有(空) あるかも 無(一切無い)
D -- 有(空でない) あるかも 外部サブセットの内容
E 有(空) -- 無(一切無い)
F 有(空) -- 有(空) あるかも 無(一切無い)
G 有(空) -- 有(空でない) あるかも 外部サブセットの内容
H 有(空でない) 内部サブセットの内容
I 有(空でない) 有(空) あるかも 内部サブセットの内容
J 有(空でない) 有(空でない) あるかも マージした内容
K 有(空でない) あるかも 内部サブセットの内容
L 有(空でない) 有(空) あるかも 内部サブセットの内容
M 有(空でない) 有(空でない) あるかも マージした内容


一方、空かどうかを考慮にいれないで作成した表は次のようになります。


表2.

No. DOCTYPE宣言 内部サブセット 外部サブセット 読み飛ばし DTD
PE
―――――――――――――――――――――――――――――――――
A -- -- -- 無(一切無い)
B -- 無(一切無い)
D -- 有(空でない) あるかも 外部サブセットの内容
H 有(空でない) 内部サブセットの内容
J 有(空でない) 有(空でない) あるかも マージした内容
K 有(空でない) あるかも 内部サブセットの内容
M 有(空でない) 有(空でない) あるかも マージした内容


これらの2つの表においてプロセッサの読み飛ばしが無いのは、
 パターンA、B、E(表1のみ)、H
です。


次にW3Cの勧告
 # 整形式性制約: 宣言した実体
 # DTDを持たない文書、パラメータ実体の参照を1つも持たない内部サブセットだけを持つ文書
とあり、指定する条件で分けると、
 DTDを持たない文書:パターンA、B、C(表1のみ)、E(表1のみ)、F(表1のみ)
 パラメータ実体参照を1つも持たない内部サブセットだけを持つ文書:パターンH
です。


読み飛ばしがないパターンとW3Cの勧告が指定する条件の違いはパターンC、Fです。
そしてパターンC、Fは表1にしかありません。このことから、
 「妥当性を検証しないプロセッサはDTDを構築するときに読み飛ばしを行ったかどうかを認識しない」

 「妥当性を検証しないプロセッサは構築したDTDが空だったとしてもそれは読み飛ばした可能性があり、DTDが無いとは言えない」
 →
 「DTDが無いという場合、内部サブセットと外部サブセットの出現が無いことと同一視して良い」
ということが推測できます。
#
# こうなると、46回で議論した「DTDはマークアップ宣言から成る」
# という記述に表現の問題がありそうです。
#

一般実体の記載位置に関する条件
"一般実体の宣言は、属性リスト宣言のデフォルト値のなかに現れるその実体に対する参照より先に宣言しなければならない。"
の条件は「一般実体参照の展開方法」に起因しているのですが、4.物理構造 の章を先頭から読み進めていると気づきにくいので検討します。


一般実体が記載できる位置は構文

# 一般実体参照の構文
[68] EntityRef ::= '&' Name ';'

# 一般実体の参照を含む構文
[67] Reference ::= EntityRef | CharRef

[9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"'
            | "'" ([^%&'] | PEReference | Reference)* "'"
[10] AttValue ::= '"' ([<&"] | Reference)* '"' | "'" ([<&'] | Reference)* "'"
[43] content ::= CharData? ((element | Reference | CDSect | PI | Comment) CharData?)*
ですから、
1. EntityValueの中
2. AttValueの中
3. content
となります。


AttValueについては、

# contentの中の開始タグにある属性値
[40] STag ::= '<' Name (S Attribute)* S? '>'
[41] Attribute ::= Name Eq AttValue

# 属性リスト宣言のデフォルト値
[52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
[53] AttDef ::= S Name S AttType S DefaultDecl
[60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
の2ヶ所に出現します。
よって、一般実体の記載できる位置は
1 . EntityValueの中
2-1. 属性リスト宣言のデフォルト値のAttValueの中
2-2. contentに現れるAttValueの中
3 . content
と整理できます。


2-2.contentに現れるAttValueの中と 3.contentで一般実体の参照を認識した場合、
すべての実体宣言を読み込み済みなので"宣言より先に"の制限は必要ありません。


次に、1.EntityValueの中で一般実体の参照を認識した場合(後の説明でわかりますが)「バイパス」します。
つまり、実体宣言をテーブルに登録する時点では展開せず、置換テキストとして登録します。
よって、参照名をキーにテーブルを検索しないので"宣言より先に"の制限は必要ありません。


最後に、2-1.属性リスト宣言のデフォルト値のAttValueの中で一般実体の参照を認識した場合、
デフォルト値の正規化処理をするので「リテラルの中でインクルード」します。
この際、参照名をキーにテーブルを検索するので"宣言より先に"の制限が必要になります。


W3Cの勧告が"宣言より先に"と明記することで、属性リスト宣言の1つで一般実体の参照を見つけた時、
ただちに展開処理しないといけない(DTDをすべて読み込んでから処理してはいけない)ということが
明確になります。

パラメータ実体の参照に対して整形式性制約がない
妥当性制約:宣言した実体は、整形式性制約:宣言した実体 の条件の補完条件しか示していません。よって整形式性制約:宣言した実体 がないとパターン漏れが起き、漏れているパターンの処理は曖昧です。

実体の参照方法の仕様整理

一般実体
▼参照方法
生成規則にあるように、
一般実体の参照は、 SYMBOL WORD SYMBOL
となります。
参照名:Nameは宣言した実体名である必要がありますが細かい条件があります。
▼妥当性を検証しないプロセッサの参照名に対する展開処理
1.実体宣言中の一般実体 :展開しないので整形式性制約は適用しません。
2.属性リスト宣言のデフォルト値中の一般実体:展開するときに整形式性制約を適用します。
3.content中一般実体/属性値の一般実体 :展開するときに整形式性制約を適用します。


[展開するときの適用方法]
1.実体名がamp, lt, gt, aposの場合(定義済み実体の場合)
1-1.置換テキストを展開する
2.実体名がamp, lt, gt, aposの場合(定義済み実体の場合)
2-1.実体名をキーにテーブルを検索する
2-2.実体名がテーブルに無い場合
2-2-1.スタンドアロン文書宣言がyesのとき
2-2-1-1.整形式性制約違反エラー
2-2-2.スタンドアロン文書宣言がnoのとき
2-2-2-1.DTDの読み飛ばしが有る場合
★ 処理不明(W3Cの勧告では触れていないので各プロセッサの仕様として規定する)
2-2-2-2.DTDの読み飛ばしが無い場合
(条件1.外部サブセットが無い
かつ、
条件2.内部サブセットがない。または、内部サブセットがあってもパラメータ実体の参照がない)
2-2-2-2-1.整形式性制約違反エラー
2-3.実体名がテーブルに有る場合
2-3-1.実体が解析対象実体の場合
2-3-1-1.再帰用のスタックに既に同名の実体名があるかチェックする
2-3-1-2.再帰用のスタックに既に同名の実体名が有る場合
2-3-1-2-1. 整形式性制約エラー
2-3-1-3.再帰用のスタックに既に同名の実体名が無い場合
2-3-1-3-1.再帰用のスタックに実体名を追加する
2-3-1-3-2.置換テキストを展開する
2-3-2.実体が解析対象外実体の場合
2-3-2-1.整形式性制約エラー


★部分についてはW3Cの勧告では不明確です。

▼妥当性を検証するプロセッサの参照名に対する展開処理
●妥当性制約:宣言した実体 の追加
妥当性を検証するプロセッサの場合、整形式性制約:宣言した実体 に加えて
妥当性制約:宣言した実体 のチェックを行います。

妥当性を検証するプロセッサは、パラメータ実体の中身や外部サブセットを読み込みますから、
妥当性制約を考慮しない状態は次のようになります。(読み飛ばしの列は考慮しなくてよいので削除する)

No. DOCTYPE宣言 内部サブセット 外部サブセット DTD チェック
PE
―――――――――――――――――――――――――――――――――
A -- -- -- 無(一切無い) 整形式性制約
B -- 無(一切無い) 整形式性制約
D -- 外部サブセットの内容
H 内部サブセットの内容 整形式性制約
J マージした内容
K 内部サブセットの内容
M マージした内容


この表で、
 内部サブセットのパラメータ実体の参照有: パターンK、M
 外部サブセット有: パターンD、J、M
ですので、
 妥当性制約の適用範囲は、パターンD、J、K、M
となります。


No. DOCTYPE宣言 内部サブセット 外部サブセット DTD チェック
PE
―――――――――――――――――――――――――――――――――
A -- -- -- 無(一切無い) 整形式性制約
B -- 無(一切無い) 整形式性制約
D -- 外部サブセットの内容 妥当性制約
H 内部サブセットの内容 整形式性制約
J マージした内容 妥当性制約
K 内部サブセットの内容 妥当性制約
M マージした内容 妥当性制約


●妥当性制約:宣言した実体 を考慮した処理

1.実体宣言中の一般実体 :展開しないので整形式性制約/妥当性制約は適用しません。
2.属性リスト宣言のデフォルト値中の一般実体:展開するときに整形式性制約/妥当性制約を適用します。
3.content中一般実体/属性値の一般実体 :展開するときに整形式性制約/妥当性制約を適用します。


[展開するときの適用方法]
1.実体名がamp, lt, gt, apos, quoteの場合(定義済み実体の場合)
1-1.置換テキストを展開する
2.実体名がamp, lt, gt, apos, quoteでない場合(定義済み実体でない場合)
2-1.実体名をキーにテーブルを検索する
2-2.実体名がテーブルに無い場合
2-2-1.スタンドアロン文書宣言がyesのとき
2-2-1-1.整形式性制約違反エラー
2-2-2.スタンドアロン文書宣言がnoのとき
2-2-2-1.条件1.外部サブセットが無い
かつ、
条件2.内部サブセットがない。または、内部サブセットがあってもパラメータ実体の参照がない)
2-2-2-1-1.整形式性制約違反エラー
2-2-2-2.その他の場合
2-2-2-2-1.妥当性制約違反エラー
2-3.実体名がテーブルに有る場合
2-3-1.実体が解析対象実体の場合
2-3-1-1.再帰用のスタックに既に同名の実体名があるかチェックする
2-3-1-2.再帰用のスタックに既に同名の実体名が有る場合
2-3-1-2-1. 整形式性制約エラー
2-3-1-3.再帰用のスタックに既に同名の実体名が無い場合
2-3-1-3-1.再帰用のスタックに実体名を追加する
2-3-1-3-2.置換テキストを展開する
2-3-2.実体が解析対象外実体の場合
2-3-2-1.整形式性制約エラー

パラメータ実体
▼参照方法
生成規則にあるように、
 パラメータ実体の参照は、 SYMBOL WORD SYMBOL
となります。


▼記載位置

パラメータ実体の記載位置は、
 1.EntityValueの中
 2.DeclSep
 3.外部サブセットのマークアップ宣言の先頭と末尾トークンを含まない位置
に記載できます。


▼パターン表

一般実体との差異
一般実体の仕様で整形式性制約の部分はチェックしません。
パラメータ実体の参照が有る場合の処理なので、パラメータ実体参照の有無が無のHとJを削除します。


No. DOCTYPE宣言 内部サブセット 外部サブセット DTD チェック
PE
―――――――――――――――――――――――――――――――――
A -- -- -- 無(一切無い) --
B -- 無(一切無い) --
D -- 外部サブセットの内容 妥当性制約
K 内部サブセットの内容 妥当性制約
M マージした内容 妥当性制約


-補足

パターン表には妥当性チェックのみがあるため、パラメータ実体の実体名がテーブルに無い場合、妥当性を検証しないプロセッサの仕様は不明確です。


▼パラメータ実体名と定義済み実体名の名前空間

前回説明した通り、実体名とパラメータ実体名の名前空間は異なります。


また、定義済み実体は、4.6章にその定義があり、
 <!ENTITY lt "&#60;">
 <!ENTITY gt ">">
 <!ENTITY amp "&#38;">
 <!ENTITY apos "'">
 <!ENTITY quot """>
とあるので、
 パラメータ実体の展開処理で定義済み実体名とのチェックは検索しなくてよい
ことが判ります。


▼妥当性を検証しないプロセッサの参照名に対する展開処理

[展開するときの適用方法]
1.実体名をキーにテーブルを検索する
2.実体名がテーブルに無い場合
2-1.★仕様なし
3.実体名がテーブルに有る場合
3-1.再帰用のスタックに既に同名の実体名があるかチェックする
3-2.再帰用のスタックに既に同名の実体名が有る場合
3-2-1. 整形式性制約エラー
3-3.再帰用のスタックに既に同名の実体名が無い場合
3-3-1.再帰用のスタックに実体名を追加する
3-3-2.置換テキストを展開する ★部分についてはW3Cの勧告では不明確です。


▼妥当性を検証するプロセッサの参照名に対する展開処理

[展開するときの適用方法]
1.実体名をキーにテーブルを検索する
2.実体名がテーブルに無い場合
2-1.スタンドアロン文書宣言がyesのとき
2-1-1.★仕様なし
2-2.スタンドアロン文書宣言がnoのとき
2-2-1.条件1.外部サブセットが無い
かつ、
条件2.内部サブセットが無い)
2-2-1-1.★仕様なし
2-2-2.その他の場合
2-2-2-1.妥当性制約違反エラー
3.実体名がテーブルに有る場合
3-1.再帰用のスタックに既に同名の実体名があるかチェックする
3-2.再帰用のスタックに既に同名の実体名が有る場合
3-2-1. 整形式性制約エラー
3-3.再帰用のスタックに既に同名の実体名が無い場合
3-3-1.再帰用のスタックに実体名を追加する
3-3-2.置換テキストを展開する ★部分についてはW3Cの勧告では不明確です。
Comment(0)

コメント

コメントを投稿する