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?

2 Answers 2

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.

6
  • 1
    This works, but gets rid of all the SOAP structure: <Envelope><Body><SomeOp>.... Is there a way to retain it? Commented Feb 20, 2014 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. Commented Feb 20, 2014 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 doesn't seem to mention namespace options Commented Feb 21, 2014 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... Commented Feb 21, 2014 at 11:20
  • I edited my answer. You might want to change your question a bit :-). Hope it helps. Commented Feb 21, 2014 at 22:32
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/>"})

Not the answer you're looking for? Browse other questions tagged or ask your own question.