Nokogiri Rails 3

Nokogiri is a simple HTML / XML parser with much of its interface borrowed from Hpricot. It uses libxml2 to parse and search, so it is very fast.

Installation

Installation is very easy. Just use the following command and add to your Gemfile

gem "nokogiri"

Quick start to parsing HTML

Parsing HTML is easy, and you can take advantage of CSS selectors or XPath queries to find things in your document:

require 'open-uri'
require 'nokogiri'

# Perform a google search
doc = Nokogiri::HTML(open('http://google.com/search?q=tenderlove'))

# Print out each link using a CSS selector
doc.css('h3.r > a.l').each do |link|
  puts link.content
end

Here is an example parsing some HTML and searching it using a combination of CSS selectors and XPath selectors:

require 'nokogiri'

doc = Nokogiri::HTML.parse(<<-eohtml)
<html>
  <head>
    <title>Hello World</title>
  </head>
  <body>
    <h1>This is an awesome document</h1>
    <p>
      I am a paragraph
        <a href="http://google.ca">I am a link</a>
    </p>
  </body>
</html>
eohtml

####
# Search for nodes by css
doc.css('p > a').each do |a_tag|
  puts a_tag.content
end

####
# Search for nodes by xpath
doc.xpath('//p/a').each do |a_tag|
  puts a_tag.content
end

####
# Or mix and match.
doc.search('//p/a', 'p > a').each do |a_tag|
  puts a_tag.content
end

###
# Find attributes and their values
doc.search('a').first['href']

Generate

require 'rubygems'
require 'nokogiri'

@builder = Nokogiri::HTML::Builder.new do |doc|
  doc.html {
    doc.head {
      doc.script {
        doc.text "alert('hello world');"
      }
      doc.style {
        doc.text "div#thing { background: red; }"
      }
      doc.title "Awesome Page" 
    }
    doc.body {
      doc.div.rad.thing! {
        doc.h1 "This is an h1"
        doc.text "This is a div with class 'rad' and id 'thing'"

        doc.div( :some_attribute => 'foo' ) {
          doc.p "This is an awesome paragraph!"
        }
      }
    }
  }
end

puts @builder.to_html

Is there an easy way to create html partials e.g. menu instead of a full HTML document?
The only workaround I’ve found is to use inner_html:

require 'rubygems'
require 'nokogiri'

@builder = Nokogiri::HTML::Builder.new do |doc|
  doc.ul {
    doc.li 'hello'
  }
end

puts @builder.doc.inner_html 
# <ul><li>hello</li></ul>
Advertisements

About me
Interested about Ruby on Rails

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: