Parsing SOAP response using SAVON response.to_hash conversion method

I am having trouble parsing a SOAP response.

Here is my code:

require 'rubygems'
require 'savon'

client = Savon::Client.new "http://1.2.3.4/xyz/abcd/fsds.wsdl"

res = client.query_unpaid_assesments do |soap,wsse|
  soap.namespaces["xmlns:SOAP-ENV"] = "http://schemas.xmlsoap.org/soap/envelope/"
  soap.namespaces["xmlns:xsi"] = "http://www.w3.org/2001/XMLSchema-instance"
  soap.namespaces["xmlns:xsd"] = "http://www.w3.org/2001/XMLSchema"

  wsse.username="xyz"
  wsse.password="123"

  soap.body = {:orderNumber => 111222333 }
end

response = Savon::Response#to_hash
hres = response.to_hash 
all_data = hres[:response][:asses_data][:date][:amount][:assesReference][:year][:cusOffCode][:serie][:number][:date][:time]

Here is the error that I am having:

undefined method to_hash for Savon::Response:Class (NoMethodError)

"res" is giving me xml response that I would like to have in hash.

I read previous related questions and they recommending to use response.to_hash , which I did and is throwing the error specified above. How can i get rid of this error and have my response into hash.

thanks for ur help

I forgot to post the body of the xml response that I would like to parse:

<soapenv:Body>
<response>
<ns203:assesData xmlns:ns203="http://asdfsd.sdfsd.zbc.org">
<ns203:date>2010-09-01</ns203:date>
<ns203:amount>34400</ns203:amount>
<ns203:asesReference>
    <ns203:year>2010</ns203:year>
    <ns203:cusOffCode>098</ns203:customsOfficeCode>
    <ns203:serie>F</ns203:serie>
    <ns203:number>524332</ns203:number>
    <ns203:date>2010-11-11</ns203:date>
    <ns203:time>10:11:103</ns203:time>
</ns203:assesReference>
</ns203:assesData>
</response>
</soapenv:Body>

Answers


I believe you need to be trying to #to_hash res itself, the returned Savon::Response object, instead of the Savon::Response class.

So hres = res.to_hash should work.

An example I found (at the end of here: http://blog.nofail.de/2010/01/savon-vs-handsoap-calling-a-service/) should give you the idea.

class SavonBankCode
  def self.zip_code(bank_code)
    client = Savon::Client.new Shootout.endpoints[:bank_code][:uri]
    response = client.get_bank { |soap| soap.body = { "wsdl:blz" => bank_code } }
    response.to_hash[:get_bank_response][:details][:plz]
  end
end

An alternative would be to parse the result with Nokogiri or similar, meaning you could do something like this:

require 'nokogiri'
response = res.xpath("//ns203:assesData", "ns203" => "http://asdfsd.sdfsd.zbc.org")
date = response.xpath("ns203:date", "ns203" => "http://asdfsd.sdfsd.zbc.org")
amount = response.xpath("ns203:amount", "ns203" => "http://asdfsd.sdfsd.zbc.org")
number = response.xpath("ns203:asesReference/ns203:number", "ns203" => "http://asdfsd.sdfsd.zbc.org")

etc. etc. Ugly as sin of course, but hey it is an (untested or refined) alternative ;)

Good luck!


You can also try response.body. It returns a hash


Need Your Help

How should the Form.Load event be used compared to its constructor method?

c# .net winforms

When initializing properties of controls or other values related to a Form I have a tendency to switch back and forth between initializing the values in the Form's constructor and then later when the

Future of the SAP RFC SDK

.net sdk sap saprfc

Is the SAP RFC SDK (wdtfuncs.ocx, wdtlog.ocx respectively Interop.SAPFunctionsOCX.dll, Interop.SAPLogonCtrl.dll) an acceptable / recommended way to connect (Microsoft) applications via RFCs with SA...