次の最小限のJavaScriptフラグメントがあります。
var xml = '<El a:title="T" a:href="H" xmlns:a="http://www.w3.org/1999/xlink" />';
var dom = new DOMParser().parseFromString(xml, 'text/xml');
xml = new XMLSerializer().serializeToString(dom);
ほとんどのブラウザーでコードを実行すると(ブラウザーのJavaScriptコンソールにコードを貼り付けるだけで)、解析されてからシリアル化されたXMLは元のXMLと同等です。たとえば、Chrome8では次のようになります。
<El xmlns:a="http://www.w3.org/1999/xlink" a:title="T" a:href="H"/>
ただし、Chrome 22では、同じコードフラグメントによってXMLが次のように変更されます。
<El xmlns:a="http://www.w3.org/1999/xlink" xlink:title="T" xlink:href="H"/>
xlink
title属性とhref属性で使用される名前空間プレフィックスはどこにも定義されていないため、XMLは無効になっていることに注意してください。ご想像のとおり、これにより、後でXMLを使用しようとするコードにあらゆる種類の問題が発生します。
これはXMLSerializerのバグですか、それともDOMのシリアル化方法に関する複雑な点が欠けていますか?
xlink
また、XMLをXLink名前空間のプレフィックスとして使用するための見かけの設定と一致させるのではなく、コードに入れることができる回避策を見つけた人はいますか?
アップデート
私はいくつかの追加のテストを行いましたが、問題はXMLSerializerがXLink名前空間を認識し、xlink
そのプレフィックスを適切に登録せずにそのプレフィックスを出力することを主張しているという事実が原因のようです。
したがって、このフラグメントは正常に機能します。
var xml = '<El a:title="T" a:href="H" xmlns:a="any-other-namespace-uri" />';
var dom = new DOMParser().parseFromString(xml, 'text/xml');
xml = new XMLSerializer().serializeToString(dom);
そこで、ここで名前空間のURLをあまり知られていないものに変更し、出力が有効になりました。
<El xmlns:a="any-other-namespace-uri" a:title="T" a:href="H"/>
次のフラグメントも正常に機能します。
var xml = '<El a:title="T" a:href="H" xmlns:a="http://www.w3.org/2000/xlink" />';
var dom = new DOMParser().parseFromString(xml, 'text/xml');
xml = new XMLSerializer().serializeToString(dom);
したがって、この場合、XLink名前空間に「expected」プレフィックスを使用すると、問題なくシリアル化されます。
<El xmlns:a="http://www.w3.org/2000/xlink" a:title="T" a:href="H"/>