Question

I'm currently using XmlSimple in Ruby to convert XML to a hash using the xml_in method. Everything is really nice, except for the fact that the resulting hash keys are all lowercase, whereas the XML element names were mixed-case.

Here's an example:

hash = XmlSimple.xml_in( xml_string, { 'KeyAttr' => 'name',
                                       'ForceArray' => false,
                                       'NoAttr' => true,
                                       'KeyToSymbol' => true,
                                       'SuppressEmpty' => "" } )

So, for example, this xml:

<aclEntry>
  <aclEntryId>Stuff here</aclEntryId>
  <principalName>Stuff here</principalName>
</aclEntry>

results in this hash:

{ :aclentryid => "Stuff Here", :principalname => "Stuff here" } 

I've looked over the documentation for XmlSimple, and didn't see any option that indicated it could maintain mixed-case in the document-to-hash conversion.

Is there any way to use XmlSimple to maintain case sensitivity in the resulting hash? If not, is there an alternative Ruby XML parser that can generate a hash that maintains case-sensitivity like this?

Was it helpful?

Solution

Combination of Nokogiri and Activesupport will help.

require 'active_support/core_ext/hash/conversions'
require 'nokogiri'
require 'pp'

xml_doc  = Nokogiri::XML("<aclEntry><aclEntryId>Stuff here</aclEntryId><principalName>Stuff here</principalName></aclEntry>")

h = Hash.from_xml(xml_doc.to_s).symbolize_keys

pp h #=> {:aclEntry=>{"aclEntryId"=>"Stuff here", "principalName"=>"Stuff here"}}

You can also do the same with ReXML and Activesupport

require 'rexml/document'
require 'pp'
include REXML
require 'active_support/core_ext/hash/conversions'

xmldoc = Document.new("<aclEntry><aclEntryId>Stuff here</aclEntryId><principalName>Stuff here</principalName></aclEntry>")

h = Hash.from_xml(xmldoc.to_s).symbolize_keys

pp h #=> {:aclEntry=>{"aclEntryId"=>"Stuff here", "principalName"=>"Stuff here"}}

EDIT : Having done a bit of reading it turns out that passing some options to SimpleXML produces the result you want, except that it doesn't symbolize the hash keys but that's a different issue.

require 'xmlsimple'
require 'pp'

xml_str = <<XML_STR
<aclEntry>
    <aclEntryId>Stuff here</aclEntryId>
    <principalName>Stuff here</principalName>
</aclEntry>
XML_STR

result = XmlSimple.xml_in xml_str, { 'ForceArray' => false, 'AttrPrefix' => true, 'KeyToSymbol' => true }

pp result # =>{:principalName=>"Stuff here", :aclEntryId=>"Stuff here"}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top