Sólo tienes que buscar los nodos de texto:
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<html>
<body>
<p>This is a text node </p>
<p> This is another text node</p>
</body>
</html>
EOT
doc.search('//text()').each do |t|
t.replace(t.content.strip)
end
puts doc.to_html
que da salida:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<p>This is a text node</p>
<p>This is another text node</p>
</body></html>
Por cierto, el ejemplo de código no funciona. at_xpath("//whatever").first
es redundante y fallará. at_xpath
encontrará solo la primera aparición, devolviendo un Nodo. first
es superfluo en ese punto, si funcionara, pero no lo hará porque Node no tiene un método first
.
tengo <data><foo>bar</foo></bar>
, la forma en que me dan en el texto "barra" sin hacer doc.xpath_at("//data/foo").children.first.content
?
Suponiendo doc
contiene el DOM analizado:
doc.to_xml # => "<?xml version=\"1.0\"?>\n<data>\n <foo>bar</foo>\n</data>\n"
conseguir la primera ocurrencia:
doc.at('foo').text # => "bar"
doc.at('//foo').text # => "bar"
doc.at('/data/foo').text # => "bar"
conseguir todas las ocurrencias y tomar la primera de ellas:
doc.search('foo').first.text # => "bar"
doc.search('//foo').first.text # => "bar"
doc.search('data foo').first.text # => "bar"
Estoy aceptando esta respuesta, no porque sea lo que quiero, sino porque contiene lo que quiero, el método de texto. ¡Gracias! – cbmanica
Solo un seguimiento: si quiere encontrar todos los nodos de texto no en blanco y está utilizando Rails, entonces tiene los métodos 'present?' Y 'blank?'. Cada uno de estos son equivalentes: 'doc.search ('// text()') map (&: text) .delete_if &: blank?' O 'doc.search ('// text()') map (&: texto) .keep_if &: presente? ' –