Generating custom XML for your rails app

{ Posted on May 13 2009 by Dan }
Tags : ,
Categories : Ruby on Rails

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”

  1. Awesome. Exactly what I was looking for. Thanks!

  2. just curious… when was this XML builder syntax introduced into rails?

  3. 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 :x ml => @posts }
    and the singular uses
    format.xml { render :x ml => @post }

    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

  4. You saved me a lot of time, thank you!

  5. 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!)

  6. Hey great job! its unbelievable easy to generate custom XML whit your solution! unfortunately there are hardly any tutorials about it. Thx a lot

  1. 2 Trackback(s)

  2. Creating custom XML in Ruby on Rails : compiled thoughts
  3. rails models are views? | the evolving ultrasaurus

Post a Comment

Powered by WP Hashcash