Cover by Leonard Richardson, Lucas Carlson

Safari, the world’s most comprehensive technology and business learning platform.

Find the exact information you need to solve a problem on the fly, or go deeper to master the technologies and skills you need to succeed

Start Free Trial

No credit card required

O'Reilly logo

11.6. Converting an XML Document into a Hash

Problem

When you parse an XML document with Document.new, you get a representation of the document as a complex data structure. You'd like to represent an XML document using simple, built-in Ruby data structures.

Solution

Use the XmlSimple library, found in the xml-simple gem. It parses an XML document into a hash.

Consider an XML document like this one:

	xml = %{
	<freezer temp="-12" scale="celcius">
	 <food>Phyllo dough</food>
	 <food>Ice cream</food>
	 <icecubetray>
	  <cube1 />
	  <cube2 />
	 </icecubetray>
	</freezer>}

Here's how you parse it with XMLSimple:

	require 'rubygems'
	require 'xmlsimple'

	doc = XmlSimple.xml_in xml

And here's what it looks like:

	require 'pp'
	pp doc
	# {"icecubetray"=>[{"cube2"=>[{}], "cube1"=>[{}]}],
	#  "food"=>["Phyllo dough", "Ice cream"],
	#  "scale"=>"celcius",
	#  "temp"=>"-12"}

Discussion

XmlSimple is a lightweight alternative to the Document class. Instead of exposing a tree of Element objects, it exposes a nested structure of Ruby hashes and arrays. There's no performance savings (XmlSimple actually builds a Document class behind the scenes and iterates over it, so it's about half as fast as Document), but the resulting object is easy to use. XmlSimple also provides several tricks that can make a document more concise and navigable.

The most useful trick is the KeyAttr one. Suppose you had a better-organized freezer than the one above, a freezer in which everything had its own name attribute:[2]

 xml = %{ <freezer temp="-12" ...

Find the exact information you need to solve a problem on the fly, or go deeper to master the technologies and skills you need to succeed

Start Free Trial

No credit card required