html - trazados - corel draw x7 unir nodos
Cómo evitar unir todo el texto de los nodos al raspar (1)
Este es un problema fácil de resolver que resulta de no leer la documentación sobre cómo se comporta el
text
cuando se usa en un NodeSet versus un Node (o Element).
La
documentación de NodeSet
dice que el
text
:
Obtenga el texto interno de todos los objetos Node contenidos
Que es lo que estamos viendo suceder con:
doc = Nokogiri::HTML(<<EOT)
<html>
<body>
<p>foo</p>
<p>bar</p>
<p>baz</p>
</body>
</html>
EOT
doc.search(''p'').text # => "foobarbaz"
porque:
doc.search(''p'').class # => Nokogiri::XML::NodeSet
En cambio, queremos obtener cada nodo y extraer su texto:
doc.search(''p'').first.class # => Nokogiri::XML::Element
doc.search(''p'').first.text # => "foo"
que se puede hacer usando el
map
:
doc.search(''p'').map { |node| node.text } # => ["foo", "bar", "baz"]
Ruby nos permite escribir eso de manera más concisa usando:
doc.search(''p'').map(&:text) # => ["foo", "bar", "baz"]
Lo mismo se aplica si estamos trabajando con HTML o XML, ya que HTML es una versión más relajada de XML.
Un nodo tiene varios métodos con alias para llegar a su texto incrustado. De la documentación :
#content ⇒ Object
También conocido como:
text
,inner_text
Devuelve el contenido de este nodo.
Cuando raspo varios nodos relacionados de HTML o XML para extraer el texto, todo el texto se une en una cadena larga, lo que hace imposible recuperar las cadenas de texto individuales.
Por ejemplo:
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"
Pero lo que quiero es:
["foo", "bar", "baz"]
Lo mismo sucede cuando se raspa XML:
doc = Nokogiri::XML(<<EOT)
<root>
<block>
<entries>foo</entries>
<entries>bar</entries>
<entries>baz</entries>
</block>
</root>
EOT
doc.search(''entries'').text # => "foobarbaz"
¿Por qué sucede esto y cómo lo evito?