2011-11-21 15 views

risposta

18

Nokogiri non ha XPath o CSS parsing. Analizza XML/HTML in un singolo DOM che è quindi possibile utilizzare la sintassi CSS o XPath nella query .

I selettori CSS vengono trasformati internamente in XPath prima di chiedere a libxml2 di eseguire la query. In quanto tale (per gli stessi identici selettori) la versione XPath sarebbe una piccola frazione più veloce, poiché il CSS non ha bisogno di essere prima convertito in XPath.

Tuttavia, la tua domanda non ha una risposta generale; dipende da cosa stai selezionando, e che aspetto ha XPath. È probabile che non scriveresti lo stesso XPath creato da Nokogiri. Ad esempio, vedere se è possibile indovinare il XPath per le seguenti due affermazioni CSS:

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 ')] 

A differenza di un browser Web, id e class attributi non hanno di cache accelerato-up, quindi selezionando per loro non aiuta. In effetti, l'interpretazione generale di div.article richiede molto più lavoro di qualcosa come div[@class='article'].

Come ha commentato @LBg, è necessario eseguire un benchmark per te se la velocità assoluta è fondamentale.

Tuttavia, vorrei suggerire questo: non preoccuparti per questo. I computer sono fast. Scrivi ciò che è più conveniente per te, il programmatore. Se un selettore CSS è più facile da creare, più veloce da digitare e più facile da comprendere quando si rivede il codice in un secondo momento, lo usa quello. Usa XPath quando devi fare cose che non puoi fare con la sintassi del selettore CSS.

Quanto tempo impiega Nokogiri per convertire un CSS ragionevolmente complesso in 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 

Meno di mezzo millisecondo.

+0

Hmm, questo è esattamente lo XPath che vorrei scrivere. :) Il secondo usa il "trucco" di classe che devi usare quando analizzi un attributo di classe HTML, che può avere più valori separati da spazi. –

+0

@Phrogz, "I selettori CSS vengono trasformati internamente in XPath prima di chiedere a libxml2 di eseguire la query. Come tale (per gli stessi identici selettori) la versione XPath sarebbe una piccola frazione più veloce, poiché il CSS non ha bisogno di essere convertito in XPath primo." Hai dimenticato di consentire il tempo di scratch della testa cercando di ricordare come scrivere l'accessor in XPath. :-) –

+3

+1 per "non preoccuparti". Zactly! Più facile da capire ha benefici a lungo termine nel mantenimento del codice. Non mi preoccupo tanto del tempo del computer, è il mio tempo trascorso a cercare di capire cosa è stato scritto che mi riguarda. –

Problemi correlati