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

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

{:tag :br, :attrs nil, :content []}require 'rubygems'
require 'nokogiri'
builder = do |xml|
         xml.root {
           xml.products {
             xml.widget {
               xml.id_ "10"
      "Awesome widget"
 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 whichvery fastand 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.

{:tag :br, :attrs nil, :content []} my_hash= Crack::XML.parse(my_xml)


Have a look here:


{:tag :br, :attrs nil, :content []}require 'json'
my_json= my_hash.to_json


{:tag :br, :attrs nil, :content []}  my_hash= JSON.parse(my_json)

Also have a look at Crack:

{:tag :br, :attrs nil, :content []}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:

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.

Posted: 05 August 2010

comments powered by Disqus