How to organize the syntax in this SOAP request packet sent with gem Savon in a ruby script?

StackOverflow https://stackoverflow.com/questions/23416491

  •  13-07-2023
  •  | 
  •  

Вопрос

I am trying to send a SOAP request to a resource on the web. It is expecting to receive this:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <DiscoverParameterValues xmlns="http://comscore.com/">
      <parameterId>loc</parameterId>
      <query xmlns="http://comscore.com/ReportQuery">
        <Parameter KeyId="geo" Value="124" />
      </query>
    </DiscoverParameterValues>
  </soap:Body>
</soap:Envelope>

This is the Ruby code that Im using to send a request that will result in an XML similar to the one above.

require 'savon'
#Connect to the Comscore API
client = Savon.client(
            wsdl:"https://api.comscore.com/KeyMeasures.asmx?WSDL", 
            basic_auth: ["username", "pw" ],
            log: true, :pretty_print_xml=>true)

And this is the XML thats generated:

<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:tns="http://comscore.com/"
              xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
              xmlns:ins0="http://comscore.com/Report"
              xmlns:ins1="http://comscore.com/ReportQuery"
              xmlns:ins2="http://comscore.com/ReportModel"
              xmlns:ins3="http://comscore.com/FetchMedia"
              xmlns:ins4="http://comscore.com/Media/Response">
  <env:Body>
    <tns:DiscoverParameterValues>
      <tns:parameterId>loc</tns:parameterId>
   ==>   <tns:query>
        <tns:Parameter>
          <tns:attributes>
            <tns:KeyId>geo</tns:KeyId>
            <tns:Value>124</tns:Value>
          </tns:attributes>
        </tns:Parameter>
    ==>  </tns:query>
    </tns:DiscoverParameterValues>
  </env:Body>
</env:Envelope>

As you can see there is a difference in how the XML from my code and the XML thats required looks. Ive marked it with "=>"

Here is the gem documentation page that Im using to structure my query:

http://savonrb.com/version2/locals.html

Ive tried playing around with this but I dont understand how to get the "attributes" to work right.

Any suggestions?


UPDATE:

After reading this post, I changed my ruby syntax to the following:

   attributes = { "KeyId"=>"geo", "Value" =>"124"}
   parameter = {
                :parameterId=>"loc",
                :query=>{ "Parameter" => { attributes: attributes}}
               }

response = client.call(:discover_parameter_values, 
                message:{:parameterId=>"loc", 
                        :query =>{ "Parameter"=> "", :attributes! => 
                                 { "Parameter" => 
                                     { "KeyId" => "geo" , "Value"=>"124" }}},
                     },
                :attributes => {"xmlns" => "http://comscore.com/" })

My XML changed to this:

    <env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xmlns:tns="http://comscore.com/"
                  xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:ins0="http://comscore.com/Report"
                  xmlns:ins1="http://comscore.com/ReportQuery"
                  xmlns:ins2="http://comscore.com/ReportModel"
                  xmlns:ins3="http://comscore.com/FetchMedia"
                  xmlns:ins4="http://comscore.com/Media/Response">
  <env:Body>
    <tns:DiscoverParameterValues xmlns="http://comscore.com/">
      <tns:parameterId>loc</tns:parameterId>
      <tns:query>
        <tns:Parameter KeyId="geo" Value="124"/>
      </tns:query>
    </tns:DiscoverParameterValues>
  </env:Body>
</env:Envelope>

So everything works EXCEPT - I cannot set "attributes" on the "query" tag.

I would like to set this as an attribute on the query: "xmlns=http://comscore.com/ReportQuery"

How do I do that?

Это было полезно?

Решение

Question: Does it work?

Savon uses the namespace qualifiert in a different way than your first example. In the following snippet the tags within have an implicit namespace as specified in the attribute xmlns.

<DiscoverParameterValues xmlns="http://comscore.com/">
  <parameterId>loc</parameterId>
  <query xmlns="http://comscore.com/ReportQuery">
    <Parameter KeyId="geo" Value="124" />
  </query>
</DiscoverParameterValues>

Savon uses a different syntax. It defines all needed namespace in the envelope and uses the prefixes per tag later. Different syntax for the same expression. SoapUI uses often the former variant, Savon the latter.

ParameterIdcomes in both cases from the namespace http://comscore.com/.

UPDATE response:

You can go different ways:

Is usually cheat: I just write fully qualified keys, eg.

...
:query => { "Parameter" => "", :attributes! =>
           { "Parameter" =>
              { "ins1:KeyId" => "geo", "ins1:Value" => "124" }}},
...

If you absolutely want to put the key as attribute on "query" then you can define it like this:

response = client.call(:discover_parameter_values, 
            message:{:parameterId=>"loc", 
                    :query =>{ "Parameter"=> "", :attributes! => 
                             { "Parameter" => 
                                 { "KeyId" => "geo" , "Value"=>"124" }}},
                    :attributes! => {'tns:query' =>
                           { "xmlns" => "http://comscore.com/ReportQuery" }
                 },
            :attributes => {"xmlns" => "http://comscore.com/" })
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top