2011-11-21 20 views

答えて

18

NokogiriにはXPathまたはCSS がありません。です。 XML/HTMLを1つのDOMに解析し、CSSまたはXPathの構文を使用してクエリにすることができます。

CSSセレクタは内部的にXPathに変換されてから、libxml2にクエリを実行するように要求されます。このように(厳密に同じセレクタのために)、XPathは最初にXPathに変換する必要がないため、XPathバージョンはほんのわずかなものになります。

しかし、あなたの質問には一般的な答えはありません。それはあなたが選択しているものと、XPathの外観に依存します。 Nokogiriが作成するのと同じXPathを書くことはないでしょう。あなたは、次の2つのCSS文のためのXPathを推測することができる場合たとえば、以下を参照してください。

puts Nokogiri::CSS.xpath_for('#foo') 
#=> //*[@id = 'foo'] 


puts Nokogiri::CSS.xpath_for 'div.article a.external' 
#=> //div[contains(concat(' ', @class, ' '), ' article ')]//a[contains(concat(' ', @class, ' '), ' external ')] 

Webブラウザとは異なり、idclass属性には、彼らが助けにはならないために選択し、何のスピードアップのキャッシュを持っていません。実際、div.articleの一般的な解釈には、div[@class='article']のようなものよりはるかに多くの作業が必要です。

@LBgがコメントしたように、絶対速度が重要な場合は、のベンチマークを行う必要があります。

しかし、私はこれを提案します:について心配しないでください。コンピュータはファストです。あなたに最も便利なもの、プログラマーを書く。後でコードを確認するときに、CSSセレクタの作成が簡単で、入力が速く、理解しやすい場合はにはを使用してください。 CSSセレクタ構文ではできないことを実行する必要がある場合は、XPathを使用します。

Nokogiriはかなり複雑なCSSをXPathに変換するのにどれくらいの時間がかかりますか?

t = Time.now 
1000.times do |i| 
    # Use a different CSS string each time to avoid built-in caching 
    css = "body#foo table#bar#{i} thead th, body#foo table#bar#{i} tbody td" 
    Nokogiri::CSS.xpath_for(css) 
end 
puts (Time.now - t)/1000 
#=> 0.000405041 

半分ミリ秒未満。

+0

うーん、それはまさに私が書くXPathだ。 :) 2番目のクラスは、HTMLクラス属性を解析するときに使用するクラス "トリック"を使用します。この属性は、複数の値をスペースで区切って指定できます。 –

+0

@Phrogz、 "CSSセレクタは内部的にXPathに変換されてからlibxml2にクエリを実行するように要求されていますので、CSSをXPathに変換する必要はないため、XPathバージョンは非常に高速になります最初。" XPathでアクセサを書き込む方法を覚えようとすると、頭が痛い時間を許すのを忘れてしまいました。 :-) –

+3

+1は "それを心配しないでください"。 Zactly!理解しやすくすると、コードのメンテナンスに長期的なメリットがあります。私はコンピュータの時間についてはそれほど心配していませんが、私が心配していることを理解しようとしています。 –

関連する問題