E4Xのバグ (SpiderMonkey) を発見してしまったかもしれない

default xml namespace = "";
var ns = new Namespace("xhtml", "http://www.w3.org/1999/xhtml");
var x = <ul xmlns="http://www.w3.org/1999/xhtml">
  <li>hoge</li>
</ul>;
<![CDATA[ x ]]>
<ul xmlns="http://www.w3.org/1999/xhtml">
  <li>hoge</li>
</ul>;
x.appendChild(<li>foo</li>);
<![CDATA[ 返り値 ]]>
<ul xmlns="http://www.w3.org/1999/xhtml">
  <li>hoge</li>
  <li>foo</li>
</ul>
x.* += <li>bar</li>;
<![CDATA[ 返り値 ]]>
<li xmlns="http://www.w3.org/1999/xhtml">hoge</li>
<li xmlns="http://www.w3.org/1999/xhtml">foo</li>
<li>bar</li>
<![CDATA[ x ]]>
<ul xmlns="http://www.w3.org/1999/xhtml">
  <li>hoge</li>
  <li>foo</li>
  <li>bar</li>
</ul>
<![CDATA[ x.* ]]>
<li xmlns="http://www.w3.org/1999/xhtml">hoge</li>
<li xmlns="http://www.w3.org/1999/xhtml">foo</li>
<li xmlns="http://www.w3.org/1999/xhtml">bar</li>

以下のようなことをしてきた。

  1. デフォルト名前空間をなくしておく
  2. E4X 初期化時にデフォルト名前空間をつけておく
  3. 名前空間をつけずに子要素を追加する

ここで疑問点

デフォルト名前空間はないし、li要素は皆名前空間が付いているので、空のXMLListが返るように見えるが、そうはならない。

<![CDATA[ x.li.toXMLString() ]]>
<li xmlns="http://www.w3.org/1999/xhtml">foo</li>
<li xmlns="http://www.w3.org/1999/xhtml">bar</li>

また、名前空間を付けると

<![CDATA[ x.ns::li.toXMLStrinig() ]]>
<li xmlns="http://www.w3.org/1999/xhtml">hoge</li>

と、初期化時のli要素のみが得られる。

また、

x.ns::li.name() // http://www.w3.org/1999/xhtml::li == QName(ns, "li")
x.li[0].name()  // li == QName("", "li")

である。

つまり、あとから追加した名前空間がないli要素はきちんと名前空間を持たずにいる。しかし、toString(),toXMLString()の文字列化の際に名前空間が上書きされれて表示されてしまっているのだ。

本来ならば

<![CDATA[ x ]]>
<ul xmlns="http://www.w3.org/1999/xhtml">
  <li>hoge</li>
  <li xmlns="">foo</li>
  <li xmlns="">bar</li>
</ul>

となるべきなのに。

おお、ついにE4Xのバグを発見!!!

と思っていたが、nanto_vi さんのE4Xの資料を見直していたら、既にそこに書いてあったでござる。の巻。