savon is converting special symbols of a xml soap parameter

77 views
Skip to first unread message

Leandro Rabindranath León

unread,
Sep 11, 2018, 11:54:52 PM9/11/18
to Savon
I'm implementing a ruby interface to soap services connecting to a special database called yardi. In order to do that, I use the savon gem.

Many of the required services have already been implemented. However, some services in yardi require as a parameter a full XML compliant with a given yardi provided xds. I'm having problems with these services.

The problem fundamentally is that savon changes the received xml and changes some characters; for example <, >, ", etc.

This is a real example of xml passed to a service:

<YsiTran xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns=""><Charges><Charge><Amount>100.0</Amount><AccountId>49610000</AccountId><ChargeCodeId>rentr</ChargeCodeId><Date>2017-01-23T00:00:00</Date><Notes>Charge with segments</Notes><PersonId>t0001306</PersonId><PostMonth>2017-04-01</PostMonth><PropertyId>385pa</PropertyId><Reference>Internet</Reference><UnitId>B3</UnitId><Segment1>collect</Segment1><Segment2>Technical</Segment2><Segment3>After due date</Segment3><Segment4>NA</Segment4><Segment5>IT</Segment5><Segment6>Owner</Segment6><Segment7>Testing</Segment7><Segment8>Testing</Segment8><Segment9>Employee</Segment9><Segment10>Sigma</Segment10><Segment11>January</Segment11><Segment12>Block 1</Segment12></Charge></Charges></YsiTran>


I'm pretty sure this xml is correct because I have tested it by using SoapUI. That is, when I put the xml to SoapUI with the given xml the service responds correctly.

Now, when I put the previous xml to savon and I see the request, I notice that the xml is transformed to

&lt;YsiTran xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot; xmlns=&quot;&quot;&gt;&lt;Charges&gt;&lt;Charge&gt;&lt;Amount&gt;100.0&lt;/Amount&gt;&lt;AccountId&gt;49610000&lt;/AccountId&gt;&lt;ChargeCodeId&gt;rentr&lt;/ChargeCodeId&gt;&lt;Date&gt;2017-01-23T00:00:00&lt;/Date&gt;&lt;Notes&gt;Charge with segments&lt;/Notes&gt;&lt;PersonId&gt;t0001306&lt;/PersonId&gt;&lt;PostMonth&gt;2017-04-01&lt;/PostMonth&gt;&lt;PropertyId&gt;385pa&lt;/PropertyId&gt;&lt;Reference&gt;Internet&lt;/Reference&gt;&lt;UnitId&gt;B3&lt;/UnitId&gt;&lt;Segment1&gt;collect&lt;/Segment1&gt;&lt;Segment2&gt;Technical&lt;/Segment2&gt;&lt;Segment3&gt;After due date&lt;/Segment3&gt;&lt;Segment4&gt;NA&lt;/Segment4&gt;&lt;Segment5&gt;IT&lt;/Segment5&gt;&lt;Segment6&gt;Owner&lt;/Segment6&gt;&lt;Segment7&gt;Testing&lt;/Segment7&gt;&lt;Segment8&gt;Testing&lt;/Segment8&gt;&lt;Segment9&gt;Employee&lt;/Segment9&gt;&lt;Segment10&gt;Sigma&lt;/Segment10&gt;&lt;Segment11&gt;January&lt;/Segment11&gt;&lt;Segment12&gt;Block 1&lt;/Segment12&gt;&lt;/Charge&gt;&lt;/Charges&gt;&lt;/YsiTran&gt;

As someone could notice, for a reason that I ignore savon changed some symbols.

I'm performing the request some like this:

client.call(service_name.intern, 
            message: { # other parameters
                       'TransactionXml' => transaction_xml })

client is a savon object and transaction_xml is a ruby string containing the xml.

Basically. what I would want is to say to savon do not convert special symbols like <. >, etc to its equivalents in xml. That is, to interpret the transaction_xml parameter as a simple ruby string.

Any clue, tip? Thanks in advance

Leandro

Jesús Gómez

unread,
Oct 25, 2020, 9:47:50 AM10/25/20
to Savon
Hi.

I know this is 2 years late, so probably is of no help for you, but I'm writing this for potential other users with the same problem.

As the documentation says about the locals for the request[1], the `message` local option allows you to pass a Hash

"you can pass the SOAP message as a Hash. Savon uses Gyoku to translate the Hash into XML".

But in your example, you are not passing a hash but a string. If you keep reading, you'll find that the `message` option also accepts objects that answer to `to_s`. That is one more posibility you have.

Lastly there is the `xml` option you could use directly. But the xml must be the complete SOAP document.

This is an example of how to give `message` a proper hash, by parsing to xml document using Nori, which will produce a Hash:

```
# Let's remember:
# transaction_xml is the xml document as an string. It is supposed to be the content of a tag named `TransactionXml`.
# service_name.intern is the name of the action

transaction_hash = Nori.new.parse(transaction_xml) # Nori does XML -> Hash
client.call(service_name.intern, message: { 'TransactionXml' => transaction_hash }) # I'm omitting (and will omit) the "other_parameters" for brevity
```
Reply all
Reply to author
Forward
0 new messages