6

I'm trying to use Savon to send requests to a webservice. The service I'm consuming requires nested namespaces, and I haven't figured out yet how to provide them on a request.

I've tried to craft the request by hand (with nokogiri, actually) and send the resulting xml:

client.call(:some_op, :message=>{:"op"=>"<elem/>"})

But savon escapes the string and sends &lt;elem/&gt;

How can I send raw xml without escaping?

loopbackbee
  • 21,962
  • 10
  • 62
  • 97

2 Answers2

16

The call should look like this:

client.call(:some_op, xml: "<elem />")

Or if you just want to set one or multiple namespaces then create a client as follows (without WSDL):

client = Savon.client(
  :endpoint => 'http://www.example.com',
  :namespace => 'urn:core.example.com',
  :namespaces => { 'ns1' => 'http://v1.example.com',
                   'ns2' => 'http://v2.example.com' },
  :log => true,
  :log_level => :debug,
  :pretty_print_xml => true
)

The namespaces are a Hash parameter.

Steffen Roller
  • 3,464
  • 25
  • 43
  • 1
    This works, but gets rid of all the SOAP structure: `...`. Is there a way to retain it? – loopbackbee Feb 20 '14 at 18:08
  • 2
    I'm afraid you can't have it both ways :-). What exactly was your problem in the first place that prevents you from using Savon standard methods? There are methods to inject additional namespaces if you need to. – Steffen Roller Feb 20 '14 at 20:33
  • Basically, I have two different namespaces, one for the operation (`tns`) and another for all the fields inside the message (`a`). I've managed to retain the message namespaces on responses with `:strip_namespaces=>false` on the client, but I can't figure out how to send the namespace definitions on a request - the [request locals documentation](http://savonrb.com/version2/locals.html) doesn't seem to mention namespace options – loopbackbee Feb 21 '14 at 11:13
  • Ideally I'd like to not deal with namespaces on hashes at all and let Savon handle it from the WSDL, but I'm not sure if that's possible... – loopbackbee Feb 21 '14 at 11:20
  • I edited my answer. You might want to change your question a bit :-). Hope it helps. – Steffen Roller Feb 21 '14 at 22:32
  • Thank you, I'll try to to create the client without the wsdl as you've shown! I've edited the question a bit to mention the namespace problems – loopbackbee Feb 24 '14 at 12:42
1

It looks like Savon internally uses the Gyoku Gem to convert ruby hashes to XML, and Gyoku will not escape hash keys ending with exclamation marks according to the documentation: https://github.com/savonrb/gyoku#special-characters

So this code works to get raw XML into the request while still using Savon to generate the envelope xml:

client.call(:some_op, :message=>{:"op!"=>"<elem/>"})

adailey
  • 163
  • 3
  • 4