Last Updated: November 13, 2016
· g33konaut

SOAP in Ruby with Savon 2 and nested attributes

So you want to consume SOAP in Ruby? Well, Savon is for you!

The sad thing is: The moment you go beyond very simple SOAP requests, you'll get radio silence from the documentation there.

Even googling around turns up a lot of things that work for Savon version 1, but are slightly different in version 2.

This post is for version 2, even tho version 3 is around the corner
Okay assume a WSDL on an endpoint server running TLSv1 and a self-signed certificate.
It also uses multiple XML namespaces and attributes on sub elements within the request.

Here's an example request:

<soapenv:Envelope xmlns:soapenv="" xmlns:xsi="" xmlns:mag="">
         <someAuthStuff xmlns:n2=""

Now we need a couple of adjustments to the Savon defaults.

Setting attributes

Now in v2 of Savon you can set attributes on the root element of the request (in our case mag:example by adding an attributes key to the request hash like this:, message: { example: {} }, attributes: {someAttr: 123})
So this base is easily covered.

Nested attributes

The important bit in this XML: The additional namespace and the xsi:type on the nested element. So how do we put the two attributes there in Savon 2?

Well, here comes the super unobvious magical pony ride: You can specify them by putting an :attributes! key with a hash for the elements you want to set attributes for. Fun!

require 'savon'
client = Savon.client(wsdl: 'wsdl/magic.wsdl', ssl_verify_mode: :none, ssl_version: :TLSv1), message: {
  someStuff: 123,
  someAuthStuff: {
    username: "abc",
    password: "test123"
  :attributes! => {
   someAuthStuff: {
     "xsi:type" => "n2:SpecialLogin",
     "xmlns:n2" => ""

Yes, yes - inconsistent use of the old and the new hash syntax, but for that one key I don't wanna switch to the old syntax everywhere else. That's why.

So now have fun, live long and prosper.

Say Thanks

6 Responses
Add your response

0 vu55r84ltn2gij1psiqnrisotqxswzipzwlvrievyawgnpq1nevwy oq7s0thxgxr7bu0kqr wd9

Hi Martin,

I have a basic doubt on Savon 2.

Is that possible to the XML file as a call request ?

example :

require 'rubygems'
require 'savon'

client = Savon.client(wsdl: 'http://myown/mine.wsdl?wsdl")
x= "SOME XML CONTENT request (which is working perfectly in soup ui)" # this line won't work now. is there any other alternate method will support this ?

Awaiting your reply

over 1 year ago ·

This is the only answer which helps me! Thanks a lot! My SOAP request is working like a charm now!

over 1 year ago ·

from the v2 doc:


If you need to, you can even shortcut Savon's Builder and send your very own XML., xml: "<envelope><body></body></envelope>")

over 1 year ago ·

Thanks for the helpful explanation and examples.
Is it possible to repeat a parameter several times, like in
message: {
param: 1,
which does of course not work since message is a hash.

over 1 year ago ·

I have XML having same node differ with id then how to create this request

<multiRef xmlns:ns2="" id="id2" soapenc:root="0" soap:encodingStyle="" xsi:type="ns4:WSFlowInput">
<listValues soapenc:arrayType="xsd:string[2]" xsi:type="soapenc:Array">
<listValues xsi:type="xsd:string">local</listValues>
<listValues xsi:type="xsd:string">remote</listValues>
<name xsi:type="xsd:string">phost</name>
<value xsi:type="xsd:string">phlls17-re0</value>

<multiRef xmlns:ns3="" id="id3" soapenc:root="0" soap:encodingStyle="" xsi:type="ns3:WSFlowInput">
   <listValues soapenc:arrayType="xsd:string[2]" xsi:type="soapenc:Array">
      <listValues xsi:type="xsd:string">local</listValues>
      <listValues xsi:type="xsd:string">remote</listValues>
   <name xsi:type="xsd:string">name</name>
   <value xsi:type="xsd:string">show interfaces extensive</value>

<multiRef xmlns:ns4="" id="id4" soapenc:root="0" soap:encodingStyle="" xsi:type="ns3:WSFlowInput">
   <listValues soapenc:arrayType="xsd:string[2]" xsi:type="soapenc:Array">
      <listValues xsi:type="xsd:string">local</listValues>
      <listValues xsi:type="xsd:string">remote</listValues>
   <name xsi:type="xsd:string">variables</name>
   <value xsi:type="xsd:string">port_num = ge-0/0/1</value>

The parameters are name and value

over 1 year ago ·

You can also specify attributes by prefixing the hash key with "@"., message: {
  someStuff: 123,
  someAuthStuff: {
    "username" => "abc",
    "password" => "test123",
    "@xsi:type" => "n2:SpecialLogin",
    "@xmlns:n2" => ""
over 1 year ago ·