Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert XML string to hash in Rails

I using some service that returns xml:

response = HTTParty.post(service_url)
response.parsed_response 
=> "\n\t<Result>\n<success>\ntrue\n</success>\n</Result>"

I need to convert this string to hash. Something like this:

response.parsed_response.to_hash
=> {:result => { :success => true } }

Which way to do this?

like image 388
Rodrigo Avatar asked Jun 13 '13 04:06

Rodrigo


1 Answers

The built-in from_xml Rails Hash method will do precisely what you want. In order to get your response.parsed_response correctly mapped to a hash, you'll need to gsub() out the newlines:

hash = Hash.from_xml(response.parsed_response.gsub("\n", "")) 
hash #=> {"Result"=>{"success"=>"true"}}

In the context of parsing a hash in Rails, objects of String type are not substantively different than those of Symbol from a general programming perspective. However, you can apply the Rails symbolize_keys method to the output:

symbolized_hash = hash.symbolize_keys
#=> {:Result=>{"success"=>"true"}} 

As you can see, symbolize_keys doesn't operate on any nested hashes, but you could potentially iterate through inner hashes and apply symbolize_keys.

The final piece of the puzzle is to convert the string "true" to the boolean true. AFAIK, there's no way to do this on your hash in place, but if you're iterating/operating on it, you could potentially implement a solution like the one suggested in this post:

def to_boolean(str)
     return true if str == "true"
     return false if str == "false"
     return nil
end

Basically, when you reach the inner key-value pair, you'd apply to_boolean() to the value, which is currently set to "true". In your example, the return value is the boolean true.

like image 89
zeantsoi Avatar answered Sep 17 '22 01:09

zeantsoi