Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get text directly inside a tag in Nokogiri

Tags:

ruby

nokogiri

I have some HTML that looks like:

<dt>
  <a href="#">Hello</a>
  (2009)
</dt>

I already have all my HTML loaded into a variable called record. I need to parse out the year i.e. 2009 if it exists.

How can I get the text inside the dt tag but not the text inside the a tag? I've used record.search("dt").inner_text and this gives me everything.

It's a trivial question but I haven't managed to figure this out.

like image 877
Mridang Agarwalla Avatar asked May 29 '12 12:05

Mridang Agarwalla


3 Answers

To get all the direct children with text, but not any further sub-children, you can use XPath like so:

doc.xpath('//dt/text()')

Or if you wish to use search:

doc.search('dt').xpath('text()')
like image 183
Casper Avatar answered Nov 12 '22 09:11

Casper


Using XPath to select exactly what you want (as suggested by @Casper) is the right answer.

def own_text(node)
  # Find the content of all child text nodes and join them together
  node.xpath('text()').text
end

Here's an alternative, fun answer :)

def own_text(node)
  node.clone(1).tap{ |copy| copy.element_children.remove }.text
end

Seen in action:

require 'nokogiri'
root = Nokogiri.XML('<r>hi <a>BOO</a> there</r>').root
puts root.text       #=> hi BOO there
puts own_text(root)  #=> hi  there
like image 12
Phrogz Avatar answered Nov 12 '22 09:11

Phrogz


The dt element has two children, so you can access it by:

doc.search("dt").children.last.text
like image 5
Chamnap Avatar answered Nov 12 '22 10:11

Chamnap