2010-01-22 10 views

Répondre

1

Cependant, si le nœud que vous recherchez n'est PAS le premier (par exemple, le 99ème), alors il n'y a pas de moyen plus rapide de sélectionner ce nœud que d'y appeler #children et index.

Vous avez raison de dire qu'il est coûteux de construire un NodeSet pour tous les enfants si vous ne voulez que le premier.

Un facteur limitatif est que libxml2 (la bibliothèque XML sous-jacente à Nokogiri) stocke les enfants d'un nœud sous la forme d'une liste chaînée. Vous devrez donc parcourir la liste (O (n)) pour sélectionner le nœud enfant souhaité.

Il serait possible d'écrire une méthode pour retourner simplement le nième enfant, sans instancier un objet NodeSet ou même ruby ​​pour tous les autres enfants. Mon conseil serait d'ouvrir une demande de fonctionnalité, au http://github.com/tenderlove/nokogiri/issues ou envoyer un courriel à la liste de diffusion nokogiri.

+0

Cela a été fait! Merci :-) http://github.com/tenderlove/nokogiri/issues#issue/211 – Steinbitglis

2

Vous pouvez essayer vous-même et comparer le résultat.

J'ai créé une référence rapide: http://gist.github.com/283825

$ ruby test.rb 
Rehearsal --------------------------------------------------- 
xpath/first()  3.290000 0.030000 3.320000 ( 3.321197) 
xpath.first  3.360000 0.010000 3.370000 ( 3.381171) 
at    4.540000 0.020000 4.560000 ( 4.564249) 
at_xpath   3.420000 0.010000 3.430000 ( 3.430933) 
children.second 0.220000 0.010000 0.230000 ( 0.233090) 
----------------------------------------- total: 14.910000sec 

         user  system  total  real 
xpath/first()  3.280000 0.000000 3.280000 ( 3.288647) 
xpath.first  3.350000 0.020000 3.370000 ( 3.374778) 
at    4.530000 0.040000 4.570000 ( 4.580512) 
at_xpath   3.410000 0.010000 3.420000 ( 3.421551) 
children.second 0.220000 0.010000 0.230000 ( 0.226846) 

De mes tests, children semble être la méthode la plus rapide.

+0

Les quatre premières approches que vous avez utilisées utilisent xpath, qui est très lent. L'approche enfants, comme mentionné dans la question, analyse le nœud parent entier, ce qui est également inacceptable. Essayez-les avec 100 fois plus de nœuds et 1/100 de tests. – Steinbitglis

+0

Merci de m'avoir montré la bibliothèque de référence en passant ... Je pense que cela pourrait être très utile dans le futur :-) – Steinbitglis

0

Une approche qui n'utilise XPath ni des résultats dans l'analyse du parent tout est d'utiliser les deux enfants # Node(), Noeud # next_sibling() et l'élément Node #?()

Quelque chose comme ça ...

Nœud # enfant est le moyen le plus rapide d'obtenir le premier élément enfant.
def first(node) 
    element = node.child 
    while element 
     if element.element? 
      return element 
     else 
      element = element.next 
     end 
    end 
    nil 
end