17

我使用一些返回 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 } }

哪种方法可以做到这一点?

4

5 回答 5

39

内置的from_xmlRailsHash方法将准确地完成您想要的操作。为了使您response.parsed_response正确映射到哈希,您需要gsub()换行:

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

在 Rails 中解析散列的上下文中,String类型对象与从一般编程角度来看的对象没有本质区别。Symbol但是,您可以将 Railssymbolize_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". 在您的示例中,返回值是 boolean true

于 2013-06-13T05:07:29.540 回答
11

使用nokogiri将 XML 响应解析为 ruby​​ 哈希。它非常快。

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

doc = Nokogiri::XML(response_body)
Hash.from_xml(doc.to_s)
于 2014-04-17T08:39:09.520 回答
3

你可以在下面试试这个:

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

Hash.from_xml(str)
# => {"result"=>{"success"=>"true"}}
于 2013-06-13T05:04:54.950 回答
2

使用宝石Nokogir

doc = Nokogiri::XML(xml_string)

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

这些教程可能会对您有所帮助。

于 2013-06-13T05:18:32.867 回答
1

我找到了一个可以做到这一点的宝石:

gem 'actionpack-xml_parser'

基本上,每个节点代表一个键。使用以下 XML:

<person><name>David</name></person>

结果参数将是:

{"person" => {"name" => "David"}}

https://github.com/eileencodes/actionpack-xml_parser

于 2021-03-14T10:25:37.680 回答