指向性メモ::2005-01-20::DOMもバグってる

ページ情報
制作日
2005-01-20T20:39:29+09:00
最終更新日
2005-01-30T22:35:53+09:00
ページ内目次

PHP5.0.3だと、DOMのsaveXML()save()がバグってる。createElement()で作られたエレメントノードは名前空間がnullになるはずなのに、親要素のデフォルト名前空間を引き継いでしまっている。

$dom = new DomDocument();
$rootNode = $dom->appendChild($dom->createElementNS("http://www.arielworks.com/", "root"));
$rootNode->appendChild($dom->createElement("child"));
print $dom->saveXML();

このようなコードを書いた場合、本来は次のようになるはずだ(見やすいように整形してある)。

<?xml version="1.0">
<root xmlns="http://www.arielworks.com/">
    <child xmlns="">
</root>

しかし、実際には、強調した部分が抜け落ちてしまい、child要素の名前空間URIが「http://www.arielworks.com/」になってしまっている。

どうやら内部処理的には、きちんと「null」を保持しているようで、save()系のメソッドを使わなければ特に問題ない。恐らく、DOMツリーを文字列に変換する処理に何か問題があるのだろう。

Comments

Name
ろばQ
Datetime
2005-01-29T23:40:07+09:00
Message
DOMの仕様にある名前空間にnullをセットすると言うのは、createElement() で作られた要素ノードは「そもそもDOMレベル1互換で名前空間と言う概念を持っていない」ので、nullを返すと言うことではないでしょうか。 仮にcreateElement()が xmlns="" を持つ要素を作るのであれば、単に <child /> となる要素ノードをどのようにDOMレベル2で作ればいいのか記になる所です (本気で解らないので)。
Name
石川
Datetime
2005-01-30T00:19:56+09:00
Message
どうやら「概念そのものがない」というのが正しいようですね。DOM2の勧告に「Note that because the DOM does no lexical checking, the empty string will be treated as a real namespace URI in DOM Level 2 methods. Applications must use the value null as the namespaceURI parameter for methods if they wish to have no namespace.」という文があったので、「『NULL』と『名前空間無し』は等価」と考えていたのですが、「in DOM Level 2 methods」という言葉を読み落としていました。勧告にも書いてありますが、「DOM2とDOM1のメソッドを同時に使うべきではない」というのが結論のようです。
Name
ろばQ
Datetime
2005-01-30T02:52:10+09:00
Message
createElement() も DOM2 Core の仕様に明記されているので、DOM2に含まれる筈で、createElement() と他の DOM2 メソッドを同時に使っても問題ないと思います。で、"the empty string will be treated as a real namespace URI in DOM Level 2 methods." は「例えば createElementNS の第一引数を "" (=empty string) にすると、namespace URI として取り扱われ (xmlns="") が生成される」と言う事を意味し、"Applications must use the value null as the namespaceURI parameter for methods if they wish to have no namespace." は「名前空間を持たない(xmlns="") なら null」ではなく、「名前空間という概念を持たないならnull」と言うことになるのではないかと思うのですが、如何でしょうか?
Name
石川
Datetime
2005-01-30T22:35:53+09:00
Message

「使うべきではない」というのはどちらかと言えば実装レベル寄りの話です。確かに、勧告にメソッド自体は書かれているので「使ってはいけない」ということは無いでしょうが、勧告の「1.1.8. XML Namespaces」の最後にあるように、混ぜるのは危険だと考えられます。

NULLの解釈についてですが、もしかするとそういうことなのかも知れません。しかし、『Namespaces in XML』には「The default namespace can be set to the empty string. This has the same effect, within the scope of the declaration, of there being no default namespace.」と書いてあり、「名前空間を持たない(xmlns="")」と「名前空間という概念がない(ドキュメント中に1回もデフォルト名前空間宣言がない)」は同値であると受け取ることも出来ます。さらに、「概念有りのノード」と「概念無しのノード」が同一文章中に同居する場合、文字列にダンプ出来なくなってしまう現象の回避方法など、「概念無し」の存在にはまだ少し疑問があります。

考えてみると「名前空間無しのXML」と言うものに関して、あまり知識がないのでCoreの部分の勧告を読み直す必要がありそうです。「名前空間という概念がないXML文章」イコール「デフォルト名前空間宣言がどこにもない」なのかも実は確信が無いので、時間があるときに、もう少し調べてみたいと思います。

Trackbacks

Trackback Ping URI

http://yudai.arielworks.com/memo/2005/01/20/203929.trackback

末尾に「9 + 6」の計算結果を繋げて下さい。例えば計算結果が「17」の場合、「203929.trackback17」です。これは機械的なトラックバックスパムを防止するための措置です。

Post a comment

Name (optional)
Email address or URI (optional)
Do the math below (required to filter comment spams)
9 + 6 + 2 =
Message (required)
Submit
連絡先、リンク、転載や複製などについては『サイト案内』をご覧ください。Powered by HIMMEL

I ♥ Validator