如何在ruby脚本中组织使用gem Savon发送的SOAP请求包中的语法?

时间:2014-05-01 20:57:54

标签: ruby-on-rails ruby savon

我正在尝试向Web上的资源发送SOAP请求。期待收到这个:

<?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>

这是我用来发送请求的Ruby代码,该请求将产生类似于上面的XML。

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)

这是生成的XML:

<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>

正如您所看到的,我的代码中的XML与所需的XML之间存在差异。我用“=&gt;”

标记了它

以下是我用来构建查询的gem文档页面:

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

我试过玩这个,但我不明白如何使“属性”正常工作。

有什么建议吗?


更新:

阅读this帖后,我将ruby语法更改为以下内容:

   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/" })

我的XML改为:

    <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>

所以一切都有效除了 - 我无法在“查询”标签上设置“属性”。

我想将此设置为查询的属性:“xmlns = http://comscore.com/ReportQuery

我该怎么做?

1 个答案:

答案 0 :(得分:0)

问题:它有效吗?

Savon以与第一个示例不同的方式使用命名空间qualifiert。 在下面的代码片段中,其中的标记具有属性xmlns中指定的隐式命名空间。

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

Savon使用不同的语法。它定义了信封中所有需要的命名空间,并在以后使用每个标记的前缀。同一表达式的语法不同。 SoapUI经常使用前者变体,后者是Savon。

ParameterId来自命名空间http://comscore.com/

更新回复:

你可以采取不同的方式:

通常是作弊:我只是写完全限定键,例如

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

如果您绝对想将密钥作为属性放在“查询”上,那么您可以这样定义:

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/" })