E4XのDOM変換
昨日(JavaScript中でのHTML表現にE4Xを提案してみる)の続き
コメントでくれたid:piro_orさんのサンプル
function xmlToDom(xml, xmlns) { var doc = (new DOMParser).parseFromString( '<root xmlns="' + xmlns + '">' + xml.toXMLString() + "</root>", "application/xml"); var imported = document.importNode(doc.documentElement, true); var range = document.createRange(); range.selectNodeContents(imported); var fragment = range.extractContents(); range.detach(); return fragment.childNodes.length > 1 ? fragment : fragment.firstChild; }
これ、すばらしい。
- 全ての要素をきちんとDOM化できる
- 内部に他の名前空間の要素があっても対応できる
- オイラのxmlToDom関数にはデメリットがある
1. 全ての要素をきちんとDOM化できる
何を当たり前な...と感じるかもしれないけど、オイラが今まで知っていた方法は
function createHTMLDocument(str){ var htmlFragment = document.implementation.createDocument(null,'html',null); var range = document.createRange(); range.setStartAfter(document.body); htmlFragment.documentElement.appendChild( htmlFragment.importNode(range.crateContextualFragment(str), true)); return htmlFragment; }
というものだった。これだと
var xml = <html> <head> <title>title</title> </head> <body> <p>hogehoge</p> </body> </html>; XML.prettyPrinting = false; var dom = createHTMLDocument(xml.toXMLString());
と作ったときに、何故か、
<html> <title>title</title> <p>hogehoge<p> </html>
となってしまって困っていたのだ。それが解消されてきちんと定義どおりのDOMツリーができあがる。
2.内部に他の名前空間の要素があっても対応できる
var xml = <div> <p>hogehoge</p> <svg xmlns="http://www.w3.org/2000/svg"> <circle cx="10" cy="10" r="10"/> </svg> </div>;