当savon解析xml
<MessageList>
<TradeMessage ID="4850644"/>
<TradeMessage ID="4850666"/>
<TradeMessage ID="4850667"/>
<TradeMessage ID="4850712"/>
</MessageList>
它返回哈希{MessageList: TradeMessage: [{@id: '123'},...,{@id: '456'}]}
但是如果xml会像
<MessageList>
<TradeMessage ID="4850644"/>
</MessageList>
它将返回{MessageList: TradeMessage: {@id: '123'}}
因此我无法遍历消息列表,因为它可以是哈希或数组。
我的代码遍历数组:
t[:message_list][:trade_message].each do |m|
TradeMessage.create(id: m[:@id])
end
在这种情况下该怎么办?我应该将xml解析器从默认的nokogiri更改为其他吗?
更新:我注意到,Hash.from_xml(string)将哈希相似地返回给savon-如果有多个标签,则返回数组;如果一个标签,则返回哈希。
我的决定:使用nokogiri文档来解析savon响应response.doc
答案 0 :(得分:1)
如果这是Savon的默认行为,我建议您查看一下您获得的结果类型并从那里进行解析:
if t[:message_list][:trade_message].is_a?(Array) # or perhaps `t[:message_list][:trade_message].respond_to?(:each)`
t[:message_list][:trade_message].each { |m| TradeMessage.create(id: m[:@id]) }
else
TradeMessage.create(id: t[:message_list][:trade_message][:@id])
end
或者,您可以将结果包装在数组中(如果尚未包装的话),并进行类似的处理:
t[:message_list][:trade_message].is_a?(Array) ? t[:message_list][:trade_message] : [t[:message_list][:trade_message]]
t[:message_list][:trade_message].each { |m| TradeMessage.create(id: m[:@id]) }
宝石的奇怪行为。可能值得研究他们的文档,看看是否可以使用某些东西来改变这种行为。
如果没有,希望对您有所帮助。如果您有任何疑问,请告诉我。
答案 1 :(得分:1)
您可以使用Ruby的splat运算符。它将始终返回一个数组。请参见下面的极端示例。
require 'awesome_print'
def return_array(elements)
return *elements
end
ap return_array([:a, :b, :c])
ap return_array(:d)