well-formed でない html で DOM を試す
Firebug で試したログをコピペ。
まず、well-formed なもので確認。
>>> var html = '<html><head><title>foo</title></head><body><img src="bar.png"/></body></html>' >>> var doc = (new DOMParser).parseFromString(html, 'text/xml') >>> doc.getElementsByTagName('title') [title] >>> doc.evaluate('//title', doc, null, 6, null).snapshotLength 1 >>> doc.evaluate('//title', doc, null, 6, null).snapshotItem(0).firstChild "foo" >>> (new XMLSerializer).serializeToString(doc) "<html><head><title>foo</title></head><body><img src="bar.png"/></body></html>"
DOMParser が正しく parse するので問題なし。
次に well-formed ではないもの。img タグの / を削った。
>>> var html2 = '<html><head><title>foo</title></head><body><img src="bar.png"></body></html>' >>> var doc2 = (new DOMParser).parseFromString(html2, 'text/xml') >>> doc2.getElementsByTagName('title') [] >>> doc2.firstChild <parsererror> >>> doc2.firstChild.textContent "XML パースエラー: タグの対応が間違っています。終了タグが必要です: </img> URL: about:blank 行番号: 1, 列番号: 65:<html><head><title>foo</title></head><body><img src="bar.png"></body></html> ----------------------------------------------------------------^"
parse に失敗すると、Document にエラー原因を入れて返す仕様らしい…。
で、この前知った innerHTML に設定する方法。
>>> var div = document.createElement('div') >>> div.innerHTML = html2 "<html><head><title>foo</title></head><body><img src="bar.png"></body></html>" >>> div.getElementsByTagName('title') [title] >>> document.evaluate('//title', div, null, 6, null).snapshotLength 0 >>> (new XMLSerializer).serializeToString(div) "<DIV><TITLE>foo</TITLE><IMG src="bar.png"/></DIV>" >>> document.evaluate('//TITLE', div, null, 6, null).snapshotLength 0
XPath でアクセスできないよ!head タグとかはどっかいっちゃうし、タグが大文字だし、well-formed になってるし。
2007/09/28 追記
できます。ごめんなさい。
>>> document.evaluate('.//title', div, null, 6, null).snapshotLength 1
以下、不要だけど一応残しておく。
小文字にして parse してみた。
>>> var html3 = (new XMLSerializer).serializeToString(div) >>> var html4 = html3.replace(/(<\/?)([A-Z]+)/g, function(s, p1, p2) { return p1 + p2.toLowerCase(); }) >>> html4 "<div><title>foo</title><img src="bar.png"/></div>" var doc4 = (new DOMParser).parseFromString(html4, 'text/xml') >>> doc4.evaluate('//title', doc4, null, 6, null).snapshotLength 1 >>> doc4.evaluate('//title', doc4, null, 6, null).snapshotItem(0).textContent "foo"
でけた。けど、ちょっとやだな…。
次はこれ試そう。