Savon 的分裂反应

Splitting response of Savon

不知何故,我正在使用 savon 的网络服务来处理returns这个响应

 {:do_deal_response=>{:do_deal_result=>"Code=000&CardNumber=0000&CardDate=12/18&PayDate=02/01/2017&BusinessName=בדיקות&Terminal=0962317010&ActionMethod=עסקה טלפונית&DealID=5349614&DealType=אשראי רגיל&DealTypeOut=עסקת חובה רגילה 0000000&OkNumber=0000000&DealDate=06/12/2016 11:00:14&PayNumber=&TotalSum=111&FirstPay=&CardName=ויזה כ.א.ל&CardNameID=2&AuthNum=0000000&DealNumber=06370507&ParamJ=J4&ErrorDesc=עסקה תקינה.&Currency=שקלים&CurrencyID=1&Manpik=ויזה כ.א.ל&ManpikID=2&Mutag=ויזה כ.א.ל&MutagID=2", :@xmlns=>"http://tempuri.org/"}} 

访问@response[:do_deal_response][:do_deal_result]显然returns字符串

"Code=000&CardNumber=0000&CardDate=12/18&PayDate=02/01/2017&BusinessName=בדיקות&Terminal=0962317010&ActionMethod=עסקה טלפונית&DealID=5349614&DealType=אשראי רגיל&DealTypeOut=עסקת חובה רגילה 0000000&OkNumber=0000000&DealDate=06/12/2016 11:00:14&PayNumber=&TotalSum=111&FirstPay=&CardName=ויזה כ.א.ל&CardNameID=2&AuthNum=0000000&DealNumber=06370507&ParamJ=J4&ErrorDesc=עסקה תקינה.&Currency=שקלים&CurrencyID=1&Manpik=ויזה כ.א.ל&ManpikID=2&Mutag=ויזה כ.א.ל&MutagID=2" 

我希望能够以带符号的散列形式访问此字符串 喜欢:

results[:code] = "000"

独立解决方案

这段代码可以帮到你。它只是围绕 & 拆分字符串,围绕 = 拆分每个部分并将它们作为键和值保存在哈希中:

response = {:do_deal_response=>{:do_deal_result=>"Code=000&CardNumber=0000&CardDate=12/18&PayDate=02/01/2017&BusinessName=בדיקות&Terminal=0962317010&ActionMethod=עסקה טלפונית&DealID=5349614&DealType=אשראי רגיל&DealTypeOut=עסקת חובה רגילה 0000000&OkNumber=0000000&DealDate=06/12/2016 11:00:14&PayNumber=&TotalSum=111&FirstPay=&CardName=ויזה כ.א.ל&CardNameID=2&AuthNum=0000000&DealNumber=06370507&ParamJ=J4&ErrorDesc=עסקה תקינה.&Currency=שקלים&CurrencyID=1&Manpik=ויזה כ.א.ל&ManpikID=2&Mutag=ויזה כ.א.ל&MutagID=2", :@xmlns=>"http://tempuri.org/"}} 

deal_result = response[:do_deal_response][:do_deal_result]

class String
  def underscore
    self.gsub(/::/, '/').
    gsub(/([A-Z]+)([A-Z][a-z])/,'_').
    gsub(/([a-z\d])([A-Z])/,'_').
    tr("-", "_").
    downcase
  end
end

results = deal_result.split('&').each_with_object({}) do |string, h|
  key, value = string.split('=')
  h[key.underscore.to_sym] = value
end

puts results
#=> {:code=>"000", :card_number=>"0000", :card_date=>"12/18", :pay_date=>"02/01/2017", :business_name=>"בדיקות", :terminal=>"0962317010", :action_method=>"עסקה טלפונית", :deal_id=>"5349614", :deal_type=>"אשראי רגיל", :deal_type_out=>"עסקת חובה רגילה 0000000", :ok_number=>"0000000", :deal_date=>"06/12/2016 11:00:14", :pay_number=>nil, :total_sum=>"111", :first_pay=>nil, :card_name=>"ויזה כ.א.ל", :card_name_id=>"2", :auth_num=>"0000000", :deal_number=>"06370507", :param_j=>"J4", :error_desc=>"עסקה תקינה.", :currency=>"שקלים", :currency_id=>"1", :manpik=>"ויזה כ.א.ל", :manpik_id=>"2", :mutag=>"ויזה כ.א.ל", :mutag_id=>"2"}

带机架

如果您安装了 Rack:

require 'rack'
puts Rack::Utils.parse_nested_query(deal_result).map { |k, v| [k.underscore.to_sym, v] }.to_h

两个答案都与您正在寻找的结构完全匹配:键值和非数组值的蛇形符号。

您可以使用以下方法代替手动解析:

require 'cgi'

parsed = CGI.parse(@response[:do_deal_response][:do_deal_result])
parsed['Code']
#=> ["000"]

由于每个键接受多个值,因此值总是包装在一个数组中。如果这让您感到困扰,您可以使用 map(或 map_values,如果您使用 Rails)再做一个转换步骤:

parsed.map { |k, v| [k.underscore.symbolize, v.size == 1 ? v.first : v] }.to_h
#=> => {:code=>"000", :card_number=>"0000", :ard_date=>"12/18", :pay_date=>"02/01/2017",...

这只会解开包含一个元素的数组,其他所有元素都将保留在数组中。