NokogiriでXPathを使ってHTML文書を検索できなかった件

いや、バグでもなんでもなく、単に自分が使い方を知らなかったというだけなのだが。

次のようなHTML文書があるとして(抜粋)、

<DIV>
  <UL>
    <LI>...</LI>
    <LI>...</LI>
    ...
  </UL>
</DIV>

LIを取りたいなぁ、と思って次のようなコードを書いてみる。

doc = Nokogiri::HTML(open('/path/to/hoge.html').read)
puts doc.xpath('//DIV/UL/LI').text

…なにも表示されない。

しかし、XPath式を小文字で書くと表示される。

puts doc.xpath('//div/ul/li').text

なぜ?
XPath式って小文字じゃないとダメって規約だったっけ?そもそも大文字小文字を区別してたっけ?HTMLには区別は無いはずだが、XMLにはあるから、XML由来のXPathもまた違いを意識するのか?*1いや、それなら大文字じゃないとマッチしない、となるべきなのに結果は真逆だ。どうなってるんだ?*2そんな思考がぐるぐる回る。

そこで気まぐれに次のようなコードを実行してみたのだが…。

doc = Nokogiri::HTML(open('/path/to/hoge.html').read)
puts doc.to_s
...
<div>
  <ul>
    <li>...</li>
    <li>...</li>
    ...
  </ul>
</div>
...

小文字になってる!NokogiriはHTML文書を小文字にして持っているってことか?だからXPath式も小文字にしないとだめなのか。

Firebugで見てみても、HTMLタブ中の表示は元々のファイル中で大文字タグが使われていようがいまいが小文字に揃えられる。HTMLでは大文字でも小文字も同じなんだから、XMLにあわせて全て小文字として扱えばいいじゃん、という考えが一般的なのか?

XHTMLのような小文字のタグしか使っていないHTML文書しか相手してこなかったから、こんなのちっとも気づかなかった。とりあえずXPath式は小文字で書いとけってことで。

*1:するはず。Nokogiri:XML().xpath()を使うとちゃんと大文字を使って大文字タグだけ検索できるし。もちろん、XPath式に小文字しか使えないわけでもない。

*2:XMLXPathに関する知識の浅さが見て取れる。本腰入れて勉強したことないんだよなぁ。