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 応答に複数の「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 応答に含まれる「out」要素が 1 つだけの場合は、次のようになります。
<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
:name 要素と :type 要素が SOAP 応答に存在しないように見えますが、応答 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 ループ (各 'out' 要素をループする) 内のように見えますが、最初の要素だけにアクセスできますか?