Преобразование строки XML в хэш в Rails

Я использую некоторую службу, которая возвращает xml:

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

Мне нужно преобразовать эту строку в хэш. Что-то вроде этого:

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

Какой способ сделать это?

Ответ 1

Встроенный from_xml Метод Rails Hash сделает именно то, что вы хотите. Чтобы ваш response.parsed_response правильно отображался в хэш, вам нужно gsub() вывести строки новой строки:

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

В контексте разбора хэша в Rails объекты типа String не существенно разные, чем те, что Symbol из общая перспектива программирования. Однако вы можете применить метод Rails symbolize_keys к выходу:

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

Как вы можете видеть, symbolize_keys не работает с любыми вложенными хешами, но вы можете итерации через внутренние хэши и применить symbolize_keys.

Последняя часть головоломки состоит в том, чтобы преобразовать строку "true" в логическое true. AFAIK, нет способа сделать это на вашем хэше на месте, но если вы выполняете итерацию/работу над ним, вы можете реализовать такое решение, как тот, который предлагается в этом сообщении:

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

В основном, когда вы достигаете внутренней пары ключ-значение, вы должны применить to_boolean() к значению, которое в настоящее время установлено на "true". В вашем примере возвращаемое значение является логическим true.

Ответ 2

Используйте nokogiri для анализа XML-ответа на хэш-код рубина. Это довольно быстро.

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

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

Ответ 3

Вы можете попробовать следующее: -

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

Выход: - что я получил

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

Спасибо

Ответ 4

Использовать gem Nokogir

doc = Nokogiri::XML(xml_string)

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

Эти tutorials могут вам помочь.