1

I am trying to hit a SOAP Service from Ruby on Rails - from SOAP UI I can hit it fine and the request XML is as below:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:mun="http://schemas.datacontract.org/2004/07/MyExternalService.Map" xmlns:mun1="http://schemas.datacontract.org/2004/07/MyExternalService.Common.Map">
   <soapenv:Header/>
   <soapenv:Body>
      <tem:GetInformationsForCoordinates>
         <!--Optional:-->
         <tem:coordReq>
            <!--Optional:-->
            <mun:Coordinates>
               <!--Zero or more repetitions:-->
               <mun:Coordinate>
                  <!--Optional:-->
                  <mun:Id>1</mun:Id>
                  <!--Optional:-->
                  <mun:QualityIndex>90</mun:QualityIndex>
                  <!--Optional:-->
                  <mun:X>-110.5322</mun:X>
                  <!--Optional:-->
                  <mun:Y>35.2108</mun:Y>
               </mun:Coordinate>
            </mun:Coordinates>
         </tem:coordReq>
         <!--Optional:-->
         <tem:analysisTypes>
            <!--Zero or more repetitions:-->
            <mun:AnalysisType>Additional</mun:AnalysisType>
         </tem:analysisTypes>
      </tem:GetInformationsForCoordinates>
   </soapenv:Body>
</soapenv:Envelope>

If I copy that exact XML into a Ruby string with request = %q(XML STRING) into savon and use the method and then in Savon call the following:

response = client.call(:get_info, xml: request)

It works as expected and I get my response - however in reality I want to be just passing the parameters to Savon. So far I have tried the following:

  coordinate = { Id: '1', X: -110.5322, Y: 35.2108, QualityIndex: 90 }
  coordinates = {Coordinates: [coordinate] }
  coordinateReq = {coordReq: {coordinates: coordinates} }
  response = client.call(:get_informations_for_coordinates, message: coordinateReq)

This fails and if I look at the XML I am sending it is below:

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://tempuri.org/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <env:Body>
    <tns:GetInformationsForCoordinates>
      <coordReq>
        <coordinates>
          <coordinates>
            <Id>1</Id>
            <X>-110.5322</X>
            <Y>35.2108</Y>
            <QualityIndex>90</QualityIndex>
          </coordinates>
        </coordinates>
      </coordReq>
    </tns:GetInformationsForCoordinates>
  </env:Body>
</env:Envelope>

In comparison to what is sent from SOAP UI I am missing the xmlns:mum namespace - is there anyway I can add it my request so that it is added to each parameter i.e. X, Y QualityIndex - also the tem which is similar to tns in my Savon call is added to the coordReq in SOAPUI but not in my Savon call - is there anyway I can add it?

Also I am having some difficulty in working out how to Build the analysisTypes and AnalysisType part of my request?

Ctrl_Alt_Defeat
  • 3,933
  • 12
  • 66
  • 116

2 Answers2

0

From the documentation:

Namespaces

If you don’t pass a namespace to Savon::Client#request, Savon will register the target namespace (“xmlns:wsdl”) for you. If you did pass a namespace, Savon will use it instead of the default one. For example:

client.request :v1, :get_user

<env:Envelope
    xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:v1="http://v1.example.com">
  <env:Body>
    <v1:GetUser>
  </env:Body>
</env:Envelope>

You can always set namespaces or overwrite namespaces set by Savon. Namespaces are stored as a simple Hash.

# setting a new namespace
soap.namespaces["xmlns:g2"] = "http://g2.example.com"

# overwriting the "xmlns:wsdl" namespace
soap.namespaces["xmlns:wsdl"] = "http://ns.example.com"

Apparently, for Savon 2, setting multiple namespaces is impossible:

I found that is not possible (for now) to set multiple namespaces on version 2 of Savon.

For now i migrate my application on Savon version 1 and it worked =)

Community
  • 1
  • 1
Uri Agassi
  • 36,848
  • 14
  • 76
  • 93
  • Sorry I should have said I am using Savon Version 2 - I have added the namespace as it shows here - http://savonrb.com/version2/globals.html but its adding multiple namespaces that I cant seem to get working where I need tem on some parameters and mun on the others as it shown in my SOAP UI request – Ctrl_Alt_Defeat Mar 24 '14 at 12:22
  • Any idea on the other part of my question - i.e - how to build up analysis response and types into my request I am passing to message: – Ctrl_Alt_Defeat Mar 24 '14 at 12:24
  • Edited my answer. I believe you should open a new question for the second part. – Uri Agassi Mar 24 '14 at 12:26
0

To use multiple namespaces you put the following type of code in your client definition

...
:namespaces => {
    "xmlns:v2" => "http://v2.example.com",
    "xmlns:v1" => "http://v1.example.com" },
...
Steffen Roller
  • 3,464
  • 25
  • 43