2017-04-24 2 views
1

Quand je gratter plusieurs nœuds associés de HTML ou XML pour extraire le texte, tout le texte est entré dans une longue chaîne, ce qui rend impossible de récupérer les chaînes de texte individuels.Comment éviter de rejoindre tout le texte à partir de nœuds quand le grattage

Par exemple:

require 'nokogiri' 

doc = Nokogiri::HTML(<<EOT) 
<html> 
    <body> 
    <p>foo</p> 
    <p>bar</p> 
    <p>baz</p> 
    </body> 
</html> 
EOT 

doc.search('p').text # => "foobarbaz" 

Mais ce que je veux est:

["foo", "bar", "baz"] 

La même chose se produit lorsque XML grattage:

doc = Nokogiri::XML(<<EOT) 
<root> 
    <block> 
    <entries>foo</entries> 
    <entries>bar</entries> 
    <entries>baz</entries> 
    </block> 
</root> 
EOT 

doc.search('entries').text # => "foobarbaz" 

Pourquoi cela se produit et comment puis-je éviter il?

Répondre

3

Il s'agit d'un problème facile à résoudre qui résulte de ne pas lire la documentation sur la façon dont text se comporte lorsqu'il est utilisé sur un NodeSet par rapport à un nœud (ou un élément).

Le NodeSet documentation dit text sera:

Obtenez le texte interne de tous les objets Node contenu

Ce qui est ce que nous voyons arriver avec:

doc = Nokogiri::HTML(<<EOT) 
<html> 
    <body> 
    <p>foo</p> 
    <p>bar</p> 
    <p>baz</p> 
    </body> 
</html> 
EOT 

doc.search('p').text # => "foobarbaz" 

parce que:

doc.search('p').class # => Nokogiri::XML::NodeSet 

Au lieu de cela, nous voulons obtenir chaque nœud et extraire le texte:

doc.search('p').first.class # => Nokogiri::XML::Element 
doc.search('p').first.text # => "foo" 

qui peut être fait en utilisant map:

doc.search('p').map { |node| node.text } # => ["foo", "bar", "baz"] 

Ruby nous permet d'écrire que de façon plus concise en utilisant:

doc.search('p').map(&:text) # => ["foo", "bar", "baz"] 

Les mêmes choses que nous appliquent travailler avec HTML ou XML, HTML est une version plus détendue de XML.

Un noeud a plusieurs méthodes d'aliasage pour obtenir son texte incorporé. De the documentation:

#content ⇒ Object

Connu également comme: text, inner_text

Retourne le contenu de ce nœud.