上のようなディレクトリ構成で(hoge.xmlはルートと「bar」ディレクトリにそれぞれある)foo.xmlはbaz.dtdをDOCTYPE宣言で外部参照参照している。また、foo.xml内には実体参照&ent;が含まれる。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test SYSTEM "./bar/baz.dtd">
<test>
&ent;
</test>
baz.dtd内には&ent;に関して実体参照宣言が書かれている。置換される実体はbaz.dtdからみてさらに外部になるhoge.xmlとする。
<!ENTITY ent SYSTEM "hoge.xml">
さて、このように書いた場合、参照されるのはルートにあるhoge.xmlでしょうか、それとも「bar」ディレクトリにあるhoge.xmlでしょうか。便宜的にルートのhoge.xmlを1、「bar」ディレクトリのhoge.xmlを2とします。
xslt_set_base()
関数などで予め設定していない限り、PHP4.3.4のxslt関数は2番のhoge.xmlを読みに行きます。
1番のhoge.xmlを読みに行きます。
無視されます。実体参照が無い、といわれてアウトです。
Mozillaははなから外部参照を無視するそうなので仕方がないとして、IE6とPHP4.3.4の動作の違いはどちらが正しいのでしょうか。試しにXHTML1.1のDTDを見てみると各モジュールを絶対URIで読み込んでいました。
Googleで検索しまくったところ同じ事に言及しているページが見つかりました。
Unless otherwise provided by information outside the scope of this specification (e.g. a special XML element type defined by a particular DTD, or a processing instruction defined by a particular application specification), relative URIs are relative to the location of the resource within which the entity declaration occurs.
『Extensible Markup Language (XML) 1.0 (Second Edition)(W3C)』より引用。
XML1.0の勧告のちょうどこの部分を根拠に1番のhoge.xmlを読みに行くのが正しいようです。つまりPHP4.3.4の動作が正しいということです。
どうやら実際にはパーサによって実装が違う部分があるようなので外部参照をするときは出来るだけ絶対URIで指定するのが安全なようです。