2013-06-13 11 views
11

I usando qualche servizio che restituisce xml:Converti stringa XML di hash in Rails

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

ho bisogno di convertire questa stringa di hash. Qualcosa del genere:

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

Quale modo per fare ciò?

+1

http://www.railstips.org/blog/archives/2008/08/11/parsing-xml-with-ruby/ –

risposta

27

Il built-in from_xml Rails Hash metodo farà esattamente quello che vuoi. Al fine di ottenere il vostro response.parsed_response correttamente mappati ad un hash, è necessario gsub() i ritorni a capo:

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

Nel contesto di analisi di un hash in Rails, oggetti di String tipo sono not substantively different di quelli di Symbol da una prospettiva di programmazione generale. Tuttavia, è possibile applicare le rotaie symbolize_keys metodo per l'output:

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

Come si può vedere, symbolize_keys non operare su qualsiasi hash nidificati, ma si potrebbe scorrere hash interni e applicare symbolize_keys.

L'ultimo tassello del puzzle consiste nel convertire la stringa "true" nella booleana true. AFAIK, non c'è modo di farlo sul tuo hash a posto, ma se si sta iterazione/operando su di esso, si potrebbe implementare una soluzione come quella suggested in this post:

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

In sostanza, quando si raggiunge l'interno coppia chiave-valore, si applica to_boolean() al valore, che è attualmente impostato su "true". Nell'esempio, il valore restituito è il valore booleano true.

+0

Si prega di guardare sul mio post grazie –

2

Si può provare questo qui di seguito: -

require 'active_support/core_ext/hash/conversions'
Hash.from_xml "\n\t<Result>\n<success>\ntrue\n</success>\n</Result>".gsub("\n", "").downcase

uscita: - quello che ho ottenuto

{"result"=>{"success"=>"true"}}

Grazie

+0

Grazie per compreso il bisogno di utilizzare in Ruby binari al di fuori! – andreofthecape

2

Usa gemma Nokogir

doc = Nokogiri::XML(xml_string) 

data = doc.xpath("//Result").map do |result| 
    [ 
    result.at("success").content 
    ] 
end 

Questi tutorials possono aiutare.

+0

spero che non darà hash esatto come ho ottenuto '# ]>]>]> ' –

+0

ha aggiornato la mia risposta. Tty questo. – rony36

10

Utilizzare nokogiri per analizzare la risposta XML all'hash rubino. È piuttosto veloce

require 'active_support/core_ext/hash' #from_xml 
require 'nokogiri' 

doc = Nokogiri::XML(response_body) 
Hash.from_xml(doc.to_s)