Dirk Bergmann

Developer, panographer. Does consultancy work from own company. Lives in Chiang Mai, Thailand.

Twitter

Convert between XML, Hash, YAML, JSON in Ruby - Conversion Cheat Sheet

Here's a little XML/JSON/YAML/Hash conversion cheat sheet for Ruby: First, let's create an XML document:

require 'rubygems' require 'nokogiri' builder = Nokogiri::XML::Builder.new do |xml|

    xml.root {


      xml.products {


        xml.widget {


          xml.id_ "10"


          xml.name "Awesome widget"


        }


      }


    }


  end

my_xml = builder.to_xml

#

require 'active_support' #if you have Rails installed

my_hash = Hash.from_xml(my_xml)

Without Rails/ActiveSupport, have a look at Crack which very fast and will usually give you enough fields. If you have attributes and a text value in the same node however (joe</person), you will only get the value back, not the attribute. Update (again): For text nodes (any node that contains a string), crack will return an attributes hash in addition to the text content.

my_hash = Crack::XML.parse(my_xml)

#

Have a look here: http://blog.jayfields.com/2008/01/ruby-hashtomod.html

#

require 'json'

my_json = my_hash**.to_json**

#

my_hash = JSON.parse(my_json)

Also have a look at Crack:

my_hash = Crack::JSON.parse(my_json)

#

my_yaml =** my_hash.to_yaml**

#

my_hash =  YAML::load(my_yaml)

#

require 'xmlsimple' my_xml = XmlSimple.xml_out(my_hash**, {'KeepRoot' => true})**

There is currently no way to preserve the attributes (like <person age="10">Joe) with such conversion from Hash to XML.

#

Joe Harris: just FYI, Crack doesn't eat the attributes it sticks them in a hidden pouch. They can be retrieved using the .attributes method. :-)

dirk: @Joe: Thanks, very helpful info! I've updated the post.

Joe Harris: Dirk, Have a look at the 0.3.1 source in file 'xml.rb' lines 83-92. The attributes method only gets added to text nodes. It could probably be hacked to add them everywhere but you'd need to watch out for side effects.

dirk: Hmm, I just rechecked and can't find the .attributes method. As of version 0.8.1 crack can either return the XML-element's text value or the attribute, not both; see here: http://railstips.org/blog/archives/2009/04/01/crack-the-easiest-way-to-parse-xml-and-json/

dirk: @Joe: You're right, I must have tried on a different type of node or I simply overlooked it. Sorry about that.

Nick Roosevelt: It sure would be nice if xml, json, and yaml string conversions to and from ruby objects were all of the same form. I guess the xml stuff would be difficult because there is not a standard way of encoding an object in xml, but at least json (.from_json as well as .to_json) and yaml (.from_json as well as .to_json) would be nice. Perhaps I will do that...

Larry: Very helpful code. I wish the ruby documentation was as clear as your code. Sometimes the documentation confuses me even more. It is easy to see what the code does. Even for a beginner like me. Thanks a lot.