実体値

実体値

[4] 実体値 (entity value) は、 実体宣言の中の引数表記です。 (SGML ではなく XML の用語です。 SGML の実体文の一種です。)

仕様書:

[5] 一般実体を宣言する実体宣言実体値で生の < を使っても、その実体を参照しようとすると XML ではどの場面であっても整形式とはならないので、 XML 仕様書は使用しないように強くすすめています。

[6] 内部実体表記実体値実体値と同じものです。

内部実体の置換文は、表記実体値の内容を、 引数実体参照と文字参照を解決したものです。

実体値についての MSXML の挙動

[1]

なぜ実際に amp や lt を参照したわけでもないのにエラーになったのか、ということ。「ライン 1、位置 2」という表示もしっくりこないものがありますし、もしかすると MSXML は内部的に何らかの XML を利用していて、その中で amp への参照が現れてエラーになったのかなぁ…などと思ったり。

(マーク付けノート — M12N のバグと MSXML <http://www.satoshii.org/markup/notes/2004/02#date23-3>)

という話が気になったので、 MSXML の挙動を調べてみました。 環境は WinXP + WinIE 6.0 です。

WinIE に XML 文書を与えると、

  1. 前書きを構文解析
  2. 一般実体の実体値を内容として構文解析
  3. 文書実現値以降を構文解析

という順序で処理を進めるようです。 前書きと文書実現値の境目は、最初に stago の文字に遭遇する手前のようです。 (stago の文字の直後が名前開始文字でなくてもその時点では何も言われません。ただし、 !?/ が直後に来ると文句を言われます。)

実体値の構文解析の段階では、 参照の有無にかかわらず (そもそも文書実現値はまだ処理していない)、 重複していないすべての一般実体宣言を処理しています。 (たぶんこの時点でグローブを作ってしまうのでしょう。) 名前の重複により無視される一般実体宣言は無視されますが、 定義済み文字実体は特別扱いされません。また、内部実体外部実体も扱いに違いはありません。

ですから、一般実体の実体値 (同じ名前の宣言が複数ある時は、最初のもの。) を内容として構文解析した時に不適当な文字列が含まれていると、誤りが発生します。

このとき、

無効な文字で名前が始まりました。リソース 'http://www.satoshii.org/markup/samp/2003/xhtml11-msxml-m12n' の実行エラーです。ライン 1、位置 2

&&

のようなメッセージがブラウザに表示されますが、

という間抜けな仕様になっている模様です。

このメッセージの場合は、元凶が XHTML m12n の実体集合中にある

<!ENTITY amp     "&#38;&#38;" ><!-- ampersand, U+0026 ISOnum -->

という記述なのですが、 この実体宣言を解釈して得られる実体値は && です。 これを構文解析すると、 & の直後 (つまりライン 1、位置 2) には名前開始文字が要求されるというわけです。

(著者に直接見えるソース上の位置ではなく、構文解析結果である実体値上の位置なんて示されても困るのですけど、手抜きしたい気持ちはよくわかります。。。)

[2] で、参照してもいない実体の中身を勝手に構文解析しちゃうのってどうなんでしょう。

SGML と XML

[6] SGML では、引数表記には実質任意の内容が記述できます。 認知されない peroero などに割当てられた文字が含まれていても問題ありません。 また、 ERO は認知されたところで結局データになります (置換可能引数データ一般実体参照は含まれないので)。

ところが、 XML では >>3 の構文の通りであり、それは許されません。 & は、文字参照一般実体参照の最初の文字ではなければなりません。 XML 解析器整形式性の検証のために SGML 的には解釈しないはずの一般実体参照を調べないといけません。 (XML名前空間を使う場合は、更に名前空間整形式性まで調べないといけません。)

[7] 実体宣言されていることという整形式制約 <IW:XML1:"#wf-entdeclared"> および妥当性制約 <IW:XML1:"#vc-entdeclared">実体値に現れる一般実体参照にも適用されるのでしょうか。 SGMLの場合 (>>6) はともかく、XMLの仕様書でこの制約についての例外は特になさそうです。

実体参照の参照先が非解析対象実体ではないこととの整形式制約 <IW:XML1:"#textent"> は、実体値内での展開に関してSE正誤表で修正されて誤りになっています (<IW:XML1:"#error">)。展開に関する節で誤りに修正されて、 参照そのものに関する節で整形式制約 = 致命的誤りとされている部分が修正されていないのは矛盾のような気がしますがこれいかに。

再帰なしの整形式制約 <IW:XML1:"#norecursion"> についても実体参照される場合は、との限定なしに、 単に再帰参照は駄目としか書いてありません。 (名無しさん)

[8] >>7 FirefoxOperaも、参照されていない実体実体値一般実体参照に関してはチェックしていない模様です。 >>1 のような動作をするWinIE致命的誤りを報告します。 (名無しさん)

[9] DOMDocumentType.entities文書型宣言されている一般実体に相当するEntity節点が入ることになっています。 参照されていない実体が含まれるのかどうかはよくわかりませんが、除外するという規定はありません。 (重複する実体宣言は反映されません。) 参照されていない節点も含めようと思ったら、置換木を作るためには一般実体参照に関するチェックもしないといけません。

でもGeckoOperaentitiesnullだったり空だったり。 (名無しさん)

[10] 適合性に関する項 <IW:XML1:"#proc-types"> に、

Validating and non-validating processors alike MUST report violations of this specification's well-formedness constraints in the content of the document entity and any other parsed entities that they read.

とか

Non-validating processors are REQUIRED to check only the document entity, including the entire internal DTD subset, for well-formedness.

とか書いてある。前者を鵜呑みにすれば、参照されていない解析対象実体整形式制約違反も検出しなければならない。 後者を鵜呑みにすれば内部解析対象実体すら整形式制約を検査しなくてもよいことになる。あるいは内部実体については内部部分集合が〜の項でカバーしているつもりなのか。 (名無しさん)

メモ