我正在尝试使用Savon与使用SOAP的遗留Web服务进行通信。关于Savon如何从响应包络中构造哈希,我遇到了一个问题。
client = Savon.client("http://my-service-endpoint/?wsdl")
response = client.request :my_soap_operation do
soap.body do |xml|
xml.in("test")
end
end
response.to_hash[:my_soap_operation_response][:out].each do |a|
puts "Return element: #{a}"
puts "Name #{a[:name]}"
puts "Type #{a[:type]}"
puts "Code #{a[:code]}"
end
结束
如果SOAP响应包含多于1个' out'元素,例如:
<mySoapOperationResponse>
<out>
<code>C1947944</code>
<name>Use</name>
<type>type 1</type>
</out>
<out>
<code>C1947946</code>
<name>name 2</name>
<type>type 2</type>
</out>
<out>
<code>C1947947</code>
<name>name 2</name>
<type>type 3</type>
</out>
</mySoapOperationResponse>
输出符合预期:
Return element: {:code=>"C1947944", :name=>"Use", :type=>"type 1"}
Name Use
Type type 1
Code C1947944
Return element: {:code=>"C1947946", :name=>"name 2", :type=>"type 2"}
Name name 2
Type type 2
Code C1947946
Return element: {:code=>"C1947947", :name=>"name 2", :type=>"type 3"}
Name name 2
Type type 3
Code C1947947
但是,如果SOAP响应只包含一个&#39; out&#39;元素,例如:
<mySoapOperationResponse>
<out>
<code>C1947944</code>
<name>name 1</name>
<type>type 1</type>
</out>
</mySoapOperationResponse>
我在控制台中看到了这个
Return element: [:code, "C1947944"]
...然后我收到错误消息
can't convert Symbol into Integer
看起来似乎在SOAP响应中不存在:name和:type元素,但是我可以通过响应XML消息看到它们。
我正在使用Savon v1.2.0。
附录
我添加了以下代码以尝试进一步调试此问题:
response = client.request :my_soap_operation do
soap.body do |xml|
xml.in("test")
end
end
pp response.to_hash
response.to_hash[:my_soap_operation_response][:out].each do |a|
pp a
puts "Return element: #{a}"
puts "Name #{a[:name]}"
puts "Type #{a[:type]}"
puts "Code #{a[:code]}"
我可以看到在响应哈希中打印出漂亮的元素。以下是控制台的快照:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<mySoapOperationResponse>
<out>
<code>C1947944</code>
<name>name 1</name>
<type>type 1</type>
</out>
</mySoapOperationResponse>
</soapenv:Body>
</soapenv:Envelope>
{:my_soap_operation_response=>
{:out=>{:code=>"C1947944", :name=>"name 1", :type=>"type 1"},
:@xmlns=>"http://namespace.removed.com/"}}
[:code, "C1947944"]
Return element: [:code, "C1947944"]
然而,它似乎在.each循环中(循环遍历每个&#39; out&#39;元素),只能访问第一个元素?
答案 0 :(得分:1)
我认为问题是,Savon在第二种情况下没有返回数组。你需要检查一下 [:out]是一个数组还是一个值,并相应地采取行动。我所做的是将单个值包装到一个元素的数组中,以保持我的程序结构简单。
def wrapped_soap_call
# prepare Savon::Client to your liking
client = Savon::Client.new do
# your stuff here
end
# call the SOAP WS
result = client.request :wsdl, :function do
# your stuff here
end
list = result.to_hash[:response][:out]
# if there was only one item list is not an array!
if list.is_a? Array
return list
else
return Array.new << list
end
end
这适合我。