document.contentType == "application/xhtml+xml"なページでの$X
document.evaluateと名前空間がわからない - by edvakf in hatenaへのレスです。
document.contentTypeが"application/xhtml+xml"の場合、名前空間があるので、通常のXPathでは要素を取得できません。resolverとprefixが必要になります。*1
で、m.twitterはHTTPヘッダーで
Content-Type: application/xhtml+xml; charaset=UTF8; charset=utf-8
を返しているので、XMLとして扱われ、そうでない大抵のサイトはHTML上でXHTMLを宣言していても、text/htmlで返すので、HTMLとして扱われます。
Content-Type: text/html; charset=utf-8
繰り返しですが、 namespace がある Document では prefix がないと要素の取得ができません( prefix がないと resolver が働かない)。なので、$X('//x:a')とすればOKなはずなんですが、$Xがうまく機能してないみたいでエラーになるみたいです。
てなわけで、を参考に修正版$Xをあげて置きました。
これを使って
$X('//x:a')
ってするとHTMLでもXMLでも取得できます。
あれ、でも本家がlookupNamespaceURIを使ってないのにはなにか理由があるのかな。うまく動いてる気がするけど。
あーOperaで動いてないみたい
[追記:2008/10/07 16:37] Operaで動いてなかったので修正。document.contentTypeって非標準なんですね。油断してた。
結局resolverだけでみるとこんな感じ。
function (prefix) { return document.createNSResolver(context).lookupNamespaceURI(prefix) || document.documentElement.namespaceURI || ""; }
[追記:2008/10/07 17:02] さらに修正、contextに指定した要素がnamespaceURIを持ってるならそれを使う作戦。
function (prefix) { return document.createNSResolver(context).lookupNamespaceURI(prefix) || context.namespaceURI || document.documentElement.namespaceURI || ""; }
これを導入したoAutoPagerizeで、下のSITEINFO使って、m.twitter.comでAutoPagerできるのを確認。
{ url: 'http://m\\.twitter\\.com/.*' ,nextLink: '//h:a[@accesskey="6"]' ,pageElement: '//h:body/h:ul/h:li' ,exampleUrl: 'http://m.twitter.com/os0x' },
*1:resolverとかprefixってなにさっていうと、名前空間は http://www.w3.org/1999/xhtml みたいにURLで確保されて、この長ったらしいURLはいちいち書きたくないから prefix を決めて代用しようぜって感じ。そのprefixと名前空間の対応を解決するのがresolverです。と、理解してるんですが、あってるか不安。あとで調べます。