WFC: In DTD
の意味XML 1.0/1.1 には、PERef に対する WFC としてこんなのがあります:
Well-formedness constraint: In DTD
Parameter-entity references MUST NOT appear outside the DTD.
さて、この outside the DTD
というのは何を指しているのでしょうか?
この制約は以前から知っていたものの、この間までは「PERef は DTD の中でしか認知されないんだから、この制約はナンセンスだよなあ」と思って端から無視していました。しかし、先日 MSE 云々を考えていたときに、「もしかして認知様相とは無関係に %foo;
という形の文字列を禁止するものだったらどうしよう?」という疑問が浮んだのです。で、改めて XML 1.0 の構文を検証することにしました。
…が、調べるまでもなく、次のことが思い浮かびました。
さて、DTD の外で、他に PERef の書けそうな場所ってどこでしょうか。勿論、タグの内部 (<foo %bar; />
) などに PERef を記述することはできませんが、これはタグの構文を参照すれば自明なことですので、わざわざ別途 WFC を設ける必要もないはずです。
ここらまで考えて、xml-users メーリングリストにでも投げて訊いてみようかと思い立ったわけですが、そのメールを書いている最中、SGML ではもう一箇所 PERef の存在が許される箇所があることをようやく思いだしたのです。それは…。
<?xml version="1.0" ?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY % TEST "CDATA" > ]> <foo><![%TEST;[<bar>]]></foo>
マーク区間宣言の状態見出し語指定部分です。SGML ではこのような記述が許されているけれども、XML はこれを許可しない! 、と。要するにそれだけ言いたいがために、この WFC は定義されたのでしょう。ほっと一安心(つーか、もっと分かりやすく書いてくれ!)。
ちなみに、上記のような例文が不可とされた理由は、恐らく文書インスタンスにおける conditional section が禁止された理由(これも個人的な推測ですが)と同じで、non-validationg processor による整形式検証のためでしょう。
例えば上記の例文は、TEST
の実体が CDATA
か RCDATA
か IGNORE
であれば well-formed で、INCLUDE
か TEMP
か空であれば not well-formed ですから、もしこの実体宣言が外部で宣言されていれば、non-validationg processor には検証する方法がなくなってしまいます。
さらに言えば、RCDATA が禁止されたのも同様の事情によるものでしょうね。蛇足の蛇足ですが。
xml-dev メーリングリストに同様の議論を見付けましたが、結論が大分違う…。三年前のスレッドに突っ込むのもアレだしなぁ…。