Generating custom XML for your rails app
Recently, I needed to generate some xml for a rails 2.3 app. What was supposed to be a fast and easy, turned out to take much longer than expected. After all, rails already provides
respond_to do |format| format.html # index.html.erb format.xml { render :xml => @posts } end
The problem is that the generated xml is very verbose. I spent some time googling and found plenty of information, but it was scattered and didn’t quite show the whole picture.
The rails api for Builder::XmlMarkup uses both an ‘xm’ and ‘xml’ object to show how to work with xml, but only the ‘xml’ object seems to work. It also doesn’t clearly show how to setup the controller or that the code should go in an xml.builder file. Similarly here, the xml object is used in the view correctly, but also fails mention anything about the controller or type of file the code should go in.
Over at xml.com, the tutorial creates an @xml instance variable of type Builder::XmlMarkup.new and then uses that object in an .rxml view (I know, its a little dated).
I was left with a bunch of puzzle pieces that didn’t quite fit together. Eventually, I figured out what needed to be done, and this is how…
First, in the controller, remove the other bits in the format.xml line so it reads
respond_to do |format| format.html # index.html.erb format.xml # index.xml.builder end
Second, you need to create an xml.builder file, in this case, index.xml.builder. Inside the xml.builder view, you have access to an ‘xml’ object that is used to generate the xml. The xml for my sample @posts object can then look something like…
xml.instruct! xml.posts do @posts.each do |post| xml.post do xml.title post.title xml.body post.body xml.published_at post.published_at xml.comments do post.comments.each do |comment| xml.comment do xml.body comment.body end end end end end end
Now, when browsing to posts.xml, you’ll now see nicely formatted xml, without all the extra cruft added when using the default rails xml generation utility. I hope that saves you some time.
8 Responses
to “Generating custom XML for your rails app”
2 Trackback(s)
- Jul 11, 2009: Creating custom XML in Ruby on Rails : compiled thoughts
- Aug 31, 2009: rails models are views? | the evolving ultrasaurus
Awesome. Exactly what I was looking for. Thanks!
just curious… when was this XML builder syntax introduced into rails?
Another way is to override the default ActiveRecord to_xml method in post.rb. This lets you easily use the same builder code in different contexts — most importantly for singular and plural outputs.
For example, this takes care of both the posts.xml and posts/20.xml requests where the plural form uses
format.xml { render
ml => @posts }
ml => @post }
and the singular uses
format.xml { render
def to_xml(options={})
if options[:builder]
build_xml(options[:builder])
else
xml = Builder::XmlMarkup.new
xml.instruct!
build_xml(xml)
end
end
private
def build_xml(xml)
xml.tag!(“created-at”, created_at, :type => :datetime)
xml.tag!(“updated-at”, updated_at, :type => :datetime)
xml.title post.title
xml.body post.body
xml.published_at post.published_at
xml.comments do
post.comments.each do |comment|
xml.comment do
xml.body comment.body
end
end
end
end
You saved me a lot of time, thank you!
I can’t believe how easy it just was to re-create a 2 page long php script which generated a xml file with a tiny bit of rails code.. and it’s a lot cleaner and easier to read! Thanks for posting your feedback.
One thing that might help others is you can use standard # comments next to the code to put a example next of the output. (thought that’s probably obvious to someone with more rails experience than me!)
Hey great job! its unbelievable easy to generate custom XML whit your solution! unfortunately there are hardly any tutorials about it. Thx a lot