How to parse SOAP response from ruby client?

request, response, ruby, soap, wsdl

Solution

If you're going to parse the XML anyway, you might as well skip SOAP4r and go with Handsoap. Disclaimer: I'm one of the authors of Handsoap.

An example implementation:

# wsdl: http://www.abundanttech.com/webservices/deadoralive/deadoralive.wsdl
DEADORALIVE_SERVICE_ENDPOINT = {
  :uri => 'http://www.abundanttech.com/WebServices/DeadOrAlive/DeadOrAlive.asmx',
  :version => 1
}

class DeadoraliveService < Handsoap::Service
  endpoint DEADORALIVE_SERVICE_ENDPOINT
  def on_create_document(doc)
    # register namespaces for the request
    doc.alias 'tns', 'http://www.abundanttech.com/webservices/deadoralive'
  end

  def on_response_document(doc)
    # register namespaces for the response
    doc.add_namespace 'ns', 'http://www.abundanttech.com/webservices/deadoralive'
  end

  # public methods

  def get_todays_birthdays
    soap_action = 'http://www.abundanttech.com/webservices/deadoralive/getTodaysBirthdays'
    response = invoke('tns:getTodaysBirthdays', soap_action)
    (response/"//NewDataSet/Table").map do |table|
      {
        :full_name => (table/"FullName").to_s,
        :birth_date => Date.strptime((table/"BirthDate").to_s, "%m/%d/%Y"),
        :death_date => Date.strptime((table/"DeathDate").to_s, "%m/%d/%Y"),
        :age => (table/"Age").to_s.gsub(/^\(([\d]+)\)$/, '\1').to_i,
        :known_for => (table/"KnownFor").to_s,
        :alive? => (table/"DeadOrAlive").to_s == "Alive"
      }
    end
  end
end

Usage:

DeadoraliveService.get_todays_birthdays

Problem

I am learning Ruby and I have written the following code to find out how to consume SOAP services: ``` require 'soap/wsdlDriver' wsdl="http://www.abundanttech.com/webservices/deadoralive/deadoralive.wsdl" service=SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver weather=service.getTodaysBirthdays('1/26/2010') ``` The response that I get back is: ``` #<SOAP::Mapping::Object:0x80ac3714 {http://www.abundanttech.com/webservices/deadoralive} getTodaysBirthdaysResult=#<SOAP::Mapping::Object:0x80ac34a8 {http://www.w3.org/2001/XMLSchema}schema=#<SOAP::Mapping::Object:0x80ac3214 {http://www.w3.org/2001/XMLSchema}element=#<SOAP::Mapping::Object:0x80ac2f6c {http://www.w3.org/2001/XMLSchema}complexType=#<SOAP::Mapping::Object:0x80ac2cc4 {http://www.w3.org/2001/XMLSchema}choice=#<SOAP::Mapping::Object:0x80ac2a1c {http://www.w3.org/2001/XMLSchema}element=#<SOAP::Mapping::Object:0x80ac2774 {http://www.w3.org/2001/XMLSchema}complexType=#<SOAP::Mapping::Object:0x80ac24cc {http://www.w3.org/2001/XMLSchema}sequence=#<SOAP::Mapping::Object:0x80ac2224 {http://www.w3.org/2001/XMLSchema}element=[#<SOAP::Mapping::Object:0x80ac1f7c>, #<SOAP::Mapping::Object:0x80ac13ec>, #<SOAP::Mapping::Object:0x80ac0a28>, #<SOAP::Mapping::Object:0x80ac0078>, #<SOAP::Mapping::Object:0x80abf6c8>, #<SOAP::Mapping::Object:0x80abed18>] >>>>>>> {urn:schemas-microsoft-com:xml-diffgram-v1}diffgram=#<SOAP::Mapping::Object:0x80abe6c4 {}NewDataSet=#<SOAP::Mapping::Object:0x80ac1220 {}Table=[#<SOAP::Mapping::Object:0x80ac75e4 {}FullName="Cully, Zara" {}BirthDate="01/26/1892" {}DeathDate="02/28/1979" {}Age="(87)" {}KnownFor="The Jeffersons" {}DeadOrAlive="Dead">, #<SOAP::Mapping::Object:0x80b778f4 {}FullName="Feiffer, Jules" {}BirthDate="01/26/1929" {}DeathDate=#<SOAP::Mapping::Object:0x80c7eaf4> {}Age="81" {}KnownFor="Cartoonists" {}DeadOrAlive="Alive">]>>>> ``` I am having a great deal of difficulty figuring out how to parse and show the returned information in a nice table, or even just how to loop through the records and have access to each element (ie. FullName,Age,etc). I went through the whole "getTodaysBirthdaysResult.methods - Object.new.methods" and kept working down to try and work out how to access the elements, but then I get to the array and I got lost. Any help that can be offered would be appreciated.

Original source