Creating XML with Ruby and Builder
by Michael Fitzgerald
|
Pages: 1, 2
Writing a Hash as XML Markup
Using Builder, the program favs.rb creates a hash called favorites and then writes it out as XML:
#!/usr/bin/ruby
require 'builder'
favorites = {
'candy' => 'Neccos', 'novel' => 'Empire of the Sun', 'holiday' => 'Easter'
}
xml = Builder::XmlMarkup.new( :target => $stdout, :indent => 2 )
xml.instruct! :xml, :version => "1.1", :encoding => "US-ASCII"
xml.favorites do
favorites.each do | name, choice |
xml.favorite( choice, :item => name )
end
end
Run it with ruby favs.rb, or just as favs, and the output will be written as:
<?xml version="1.1" encoding="US-ASCII"?>
<favorites>
<favorite item="candy">Neccos<favorite>
<favorite item="holiday">Easter<favorite>
<favorite item="novel">Empire of the Sun<favorite>
<favorites>
The top line of the code hints at where to find the Ruby interpreter (#!/usr/bin/ruby). The Builder library is loaded, and the favorites hash is defined with three name/value pairs. The Builder object xml is instantiated. The instruct! method creates an XML declaration with an explicit target and pseudo-attributes (although the document can pass as XML 1.0, I changed version to 1.1 in the method just to show how it is done).
A block is invoked on favorites (note that you can replace do-end with braces). For each pair in the hash, an element is written using the hash name as an attribute value, and the hash value (read in as the argument choice) as content for the element. As you can guess, using Builder in this way could help conveniently export large numbers of pairs to XML.
Creating a Valid XHTML Document
Finally, I'll touch on a few more methods and techniques for writing a valid XHTML document with Builder. Here is a program (xhtml.rb) that creates the document:
#!/usr/bin/ruby
require 'builder'
x = Builder::XmlMarkup.new(:target => $stdout, :indent => 1)
x.instruct!
x.declare! :DOCTYPE, :html, :PUBLIC, "-//W3C//DTD XHTML 1.0 Strict//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
x.html( "xmlns" => "http://www.w3.org/1999/xhtml" ) {
x.head {
x.title "XHTML 1.0 example"
x.style( "type"=>text/css" ) { x.text! "h1 {font-family:tahoma,sans-serif;font-size:18pt;color:blue} body{font-family:georgia,serif}"
}
}
x.body {
x.h1 "Hello from Builder"
x.p "A Ruby library that facilitates the programatic generation of XML."
x.p { |y| y <<"Methods of interest from <code<Builder::XmlMarkup</code> }
x.ul {
x.li "cdata!"
x.li "comment!"
x.li "declare!"
x.li "instruct!"
x.li "new"
}
x.p{ |y| y << "Methods of interest from "; x.code "Builder::XmlBase"; y << ":" }
x.ul {
x.li "<<"
x.li "new"
x.li "text!"
}
}
}
The declare! method produces a document type declaration for the strict XHTML 1.0 document type definition using symbols and strings. The style element specifies a type attribute and then uses the text! method to write a little CSS. This is an alternative to placing content in the first argument, as shown in this snippet:
x.style("h1 {font-family:tahoma,sans-serif;font-size:18pt;color:blue} body{font-
family:georgia,serif}", "type"=>"text/css" )
Probably the most interesting code are those lines that create paragraphs that have mixed content (embedded code elements with text). Both statements use the block argument |y| and then append text to it using the << method. The first one embeds tags in the text; the second creates the tag with code, separating statements with semicolons.
Builder is one of the most easy-to-use toolsets I've found to generate XML markup on the fly, in any language. Though I've only scratched the surface with some of its possible uses, I think, if you have been playing with the code along the way, you've got the basics down and you're ready to put Builder to work.
|
Related Reading Programming Ruby |
Share your experience in our forums.
(* You must be a member of XML.com to use this feature.)
Comment on this Article
| Titles Only | Titles Only | Newest First |
- An alternative to Builder
2007-02-23 12:52:27 easco [Reply]
An alternative to Builder which I found particularly useful for my situation was the Ruby "ERB" module.
ERB stands for Embedded Ruby (I think) and is a tool used by Rails to manage HTML documents with Ruby code embedded in them. The nice thing about ERB is that it was installed already in my Ruby distribution so I didn't have to go to the gems to get it.
ERB and Builder are really aimed at two different things, and each can be used in different situations. For my needs, ERB was easier to use than builder. If you need to generate HTML/XHTML from Ruby, you might look into ERB as well.
http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/
- Factual Error
2006-07-02 15:49:10 newuser007 [Reply]
"It's a lightweight XML builder that originally came from the the Rails project. "
No. Builder was created before Rails existed, and was later bundled into the Rails distribution.
- Syntax errors
2006-01-06 04:40:15 F. van den Berg [Reply]
Nice article. I could even understand it without ever having worked with Ruby!
Trying the examples I found 2 syntax errors in the xhtml.rb file:
- the double quotes before 'text/css' in: x.style( "type"=>text/css" ) .....
- the double quotes after '' x.p { |y| y <<"Methods of interest from <code<Builder::XmlMarkup</code>
Add them and the example works fine!
- Installing builder
2006-01-05 15:57:10 man(1) [Reply]
Very nice way to generate xml, thanks for the article.
I had to adapt your instructions slightly to get builder installed on Debian without gem putting things where it shouldn't. Perhaps these notes will be useful.
0) Obviously you've already installed ruby, irb, ri, rake, using the Debian packages.
1) After downloading RubyGems, configure with:
ruby ./setup.rb config --prefix=/usr/local --sysconfdir=/usr/local/etc --siteruby=/usr/local/lib/site_ruby
Then ruby ./setup.rb install
It's a good idea not to do this as root; set up perms on /usr/local appropriately. Just in case gem tries to violate the FHS!
2) export GEM_HOME=/usr/local/lib/ruby/gems
3) gem install builder
4) export RUBYOPT=rubygems
5) irb --simple-prompt
>> require_gem 'builder'
=> true
>> x = Builder::XmlMarkup.new(:target => $stdout, :indent => 1)
<inspect/>
=> #<IO:0xb7ca3000>
>> exit
irb won't load builder with a simple require, but require_gem works. Not necessary when just running ruby.
6) Fix a couple of missing close quotes in xhtml.rb (lines 14 & 26), and as long as you've got the two exports defined above, works beautifully.
Cheers!
- Version 1.8.4
2006-01-05 10:30:30 Mike Fitzgerald [Reply]
Since the time I wrote the article, Ruby version 1.8.4 became available (on 12/24/2005). Find it at http://www.ruby-lang.org/en/20020102.html. Also the reference to "last year" at the beginning of the article refers to 2004 (I wrote the article in 2005).
- Version 1.8.4
2007-12-14 03:35:04 venkat1246 [Reply]
I had problems with builder.
I installed builder gem on my ubuntu 7.x machine with ruby 1.8.6 and installed irb
require 'rubygems/builder'
x = Builder::XmlMarkup.new(:target => $stdout, :indent => 1)
running the above throws me an error texting
uninitialized constant Builder (NameError)
what might be the obvious reason? am I missing any fine grain here?
- Version 1.8.4

