rubysavon

Ruby Savon Parse Additional Option


I use Savon with SOAP requests. I try to send structure below with USD currency:

'urn2:Amt' => {
  'urn2:InstdAmt Ccy="USD"' => 1.00
},

Unfortunately SAVON misinterprets this and send something like this

<urn2:Amt><urn2:InstdAmt Ccy="USD">1.0</urn2:InstdAmt>Ccy="USD"&gt;</urn2:Amt>

I'm making a mistake somewhere, the correct structure should look like this:

<urn2:Amt>
  <urn2:InstdAmt Ccy="USD">1.00</urn2:InstdAmt>
</urn2:Amt>

Can you give me a hint?


Solution

  • Savon uses gyoku for xml generation so you can leverage that syntax to generate the xml you are looking for.

    Per Explicit XML Attributes in the docs:

    In addition to using the :attributes! key, you may also specify attributes through keys beginning with an "@" sign. Since you'll need to set the attribute within the hash containing the node's contents, a :content! key can be used to explicity set the content of the node. The :content! value may be a String, Hash, or Array.

    So in your example

    client = Savon::Client.new(endpoint: 'http://example.com', namespace: 'http://v1.example.com') 
    locals = {message: {"Amt"=>{"InstdAmt"=>{"@Ccy"=>"USD", :content!=>1.0}}}}
    Savon::Builder.new('example',c.wsdl,c.globals,locals).build_document
    

    This will generate the following xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://v1.example.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
       <env:Body>
          <wsdl:example>
             <Amt>
                <InstdAmt Ccy="USD">1.0</InstdAmt>
             </Amt>
          </wsdl:example>
       </env:Body>
    </env:Envelope>