Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 提取可能是或可能不是数组的哈希键_Ruby On Rails_Json_Ruby_Hash - Fatal编程技术网

Ruby on rails 提取可能是或可能不是数组的哈希键

Ruby on rails 提取可能是或可能不是数组的哈希键,ruby-on-rails,json,ruby,hash,Ruby On Rails,Json,Ruby,Hash,我正在进行一个返回XML(JSON也可用)的API调用,响应体将显示错误(如果有)。可能只有一个或多个错误。当XML(或JSON)被解析为散列时,当存在多个错误时,保存错误的键将是一个数组,但当仅存在一个错误时,它将只是一个标准键。这使得解析变得很困难,因为我似乎无法找到一行同时适合这两种情况的代码 当出现一个错误时,对API的调用将返回此值 <?xml version=\"1.0\" encoding=\"utf-8\"?><response><version&g

我正在进行一个返回XML(JSON也可用)的API调用,响应体将显示错误(如果有)。可能只有一个或多个错误。当XML(或JSON)被解析为散列时,当存在多个错误时,保存错误的键将是一个数组,但当仅存在一个错误时,它将只是一个标准键。这使得解析变得很困难,因为我似乎无法找到一行同时适合这两种情况的代码

当出现一个错误时,对API的调用将返回此值

<?xml version=\"1.0\" encoding=\"utf-8\"?><response><version>1.0</version><code>6</code><message>Data validation failed</message><errors><error><parameter>rptFilterValue1</parameter><message>Parameter is too small</message></error></errors></response>
当出现多个错误时

<?xml version=\"1.0\" encoding=\"utf-8\"?><response><version>1.0</version><code>6</code><message>Data validation failed</message><errors><error><parameter>rptFilterValue1</parameter><message>Parameter is too small</message></error><error><parameter>rptFilterValue2</parameter><message>Missing required parameter</message></error></errors></response>
我使用以下方法将XML转换为哈希

Hash.from_xml(response.body).deep_symbolize_keys
这将返回以下哈希值

当只有一个错误时,哈希如下所示

{:response=>{:version=>"1.0", :code=>"6", :message=>"Data validation failed", :errors=>{:error=>{:parameter=>"rptFilterValue1", :message=>"Parameter is too small"}}}}
{:response=>{:version=>"1.0", :code=>"6", :message=>"Data validation failed", :errors=>{:error=>[{:parameter=>"rptFilterValue1", :message=>"Parameter is too small"}, {:parameter=>"rptFilterValue2", :message=>"Missing required parameter"}]}}}
data = Hash.from_xml(response.body).deep_symbolize_keys
if data[:response].has_key?(:errors)
  errors = data[:response][:errors][:error].map{|x| "#{x.values[0]} #{x.values[1]}"}
当有2个错误时,哈希如下所示

{:response=>{:version=>"1.0", :code=>"6", :message=>"Data validation failed", :errors=>{:error=>{:parameter=>"rptFilterValue1", :message=>"Parameter is too small"}}}}
{:response=>{:version=>"1.0", :code=>"6", :message=>"Data validation failed", :errors=>{:error=>[{:parameter=>"rptFilterValue1", :message=>"Parameter is too small"}, {:parameter=>"rptFilterValue2", :message=>"Missing required parameter"}]}}}
data = Hash.from_xml(response.body).deep_symbolize_keys
if data[:response].has_key?(:errors)
  errors = data[:response][:errors][:error].map{|x| "#{x.values[0]} #{x.values[1]}"}
当我第一次测试API响应时,我有多个错误,所以我获取错误消息的方式如下

{:response=>{:version=>"1.0", :code=>"6", :message=>"Data validation failed", :errors=>{:error=>{:parameter=>"rptFilterValue1", :message=>"Parameter is too small"}}}}
{:response=>{:version=>"1.0", :code=>"6", :message=>"Data validation failed", :errors=>{:error=>[{:parameter=>"rptFilterValue1", :message=>"Parameter is too small"}, {:parameter=>"rptFilterValue2", :message=>"Missing required parameter"}]}}}
data = Hash.from_xml(response.body).deep_symbolize_keys
if data[:response].has_key?(:errors)
  errors = data[:response][:errors][:error].map{|x| "#{x.values[0]} #{x.values[1]}"}
但是,当只有一个错误时,代码会以参数的未定义方法“值”出错

我发现的唯一实际解决方法是测试错误键的类。当数组使用一种方法进行提取时,哈希使用另一种方法

if data[:response][:errors][:error].class == Array
  errors = data[:response][:errors][:error].map{|x| "#{x.values[0]} #{x.values[1]}"}
else
  errors = data[:response][:errors][:error].map{|x| "#{x[1]}"}
end
但我只是讨厌它。必须有一种方法从一个可能是数组也可能不是数组的键中提取xml/json数据。解决方案可能是从xml到哈希的转换,而不是在解析实际哈希时。我在网上找不到任何东西

我将感谢任何帮助或提示。

如果您使用的是Rails,如果您可以执行
,则可以使用。请先挖掘

single = {:response=>{:version=>"1.0", :code=>"6", :message=>"Data validation failed", :errors=>{:error=>{:parameter=>"rptFilterValue1", :message=>"Parameter is too small"}}}}

Array.wrap(single.dig(:response, :errors, :error))
这将返回大小为1的数组:

[
  {
      :message => "Parameter is too small",
    :parameter => "rptFilterValue1"
  }
]
对于倍数:

multiple = {:response=>{:version=>"1.0", :code=>"6", :message=>"Data validation failed", :errors=>{:error=>[{:parameter=>"rptFilterValue1", :message=>"Parameter is too small"}, {:parameter=>"rptFilterValue2", :message=>"Missing required parameter"}]}}}

Array.wrap(multiple.dig(:response, :errors, :error))
这将返回大小为2的数组:

[
  {
      :message => "Parameter is too small",
    :parameter => "rptFilterValue1"
  },
  {
      :message => "Missing required parameter",
    :parameter => "rptFilterValue2"
  }
]

您可以使用
Nokogiri
xpath
解析XML,即使选择器指出单个元素,也会返回数组

errors=Nokogiri::XML(XML\u响应).xpath('//error')
errors.map{| e | e.children.each_with_object({}){| x,h | h[x.name]=x.content}
带有单个错误的API响应给出

=>[{“参数”=>“rptFilterValue1”,“消息”=>“参数太小”}]
和API结果,并出现多个错误

<?xml version=\"1.0\" encoding=\"utf-8\"?><response><version>1.0</version><code>6</code><message>Data validation failed</message><errors><error><parameter>rptFilterValue1</parameter><message>Parameter is too small</message></error><error><parameter>rptFilterValue2</parameter><message>Missing required parameter</message></error></errors></response>
=>[{“参数”=>“rptFilterValue1”,“消息”=>“参数太小”},{“参数”=>“rptFilterValue2”,“消息”=>“缺少所需参数”}]

如果没有
错误
元素,您将得到一个空数组。

旁注:使用
对象#is_a?
而不是直接的类比较;后者对于所有派生类都会失败<代码>数据[:响应][:错误][:错误]。\u是?(数组)
(或者您可以将类与不等式进行比较:
数据[:响应][:错误][:错误].class谢谢Jay。所以wrap方法使键成为数组…除非它已经是数组,否则它是有意义的!是的。它基本上与您所做的一样,但解决了一些边缘情况,并将其包装到公共类方法中。它的代码很短: