通过Ruby的SOAP接口访问Bing翻译Api

通过Ruby的SOAP接口访问Bing翻译Api,ruby,web-services,soap,bing-api,savon,Ruby,Web Services,Soap,Bing Api,Savon,我正在尝试使用Bing Translator SOAP API,因为在HTTP API中,由于UTF-8序列化,对于不太大的请求,我得到的414请求太长 所以,我正在尝试使用SavonSOAP工具包将它从HTTP接口切换到SOAP接口 我的工作流程如下所示,但未显示: WSDL_URI = 'http://api.microsofttranslator.com/V2/soap.svc?wsdl' get_access_token client = Savon.client(wsdl: WSDL

我正在尝试使用Bing Translator SOAP API,因为在HTTP API中,由于UTF-8序列化,对于不太大的请求,我得到的414请求太长

所以,我正在尝试使用SavonSOAP工具包将它从HTTP接口切换到SOAP接口

我的工作流程如下所示,但未显示:

WSDL_URI = 'http://api.microsofttranslator.com/V2/soap.svc?wsdl'

get_access_token
client = Savon.client(wsdl: WSDL_URI, headers: {'Authorization' => "Bearer #{@access_token['access_token']}"})

params = {
  'from'        => 'ru',
  'to'          => 'en',
  'text'        => 'Это текст для перевода',
  'category'    => 'general',
  'contentType' => 'text/plain'
}

result = client.call(:translate, message: params)
然后执行SOAP请求:

SOAP request: http://api.microsofttranslator.com/V2/soap.svc

Authorization: Bearer http%3a%2f%2fschemas.xmlsoap.org%2fws%2f2005%2f05%2fidentity%2fclaims%2fnameidentifier=invest_amurobl_ru&http%3a%2f%2fschemas.microsoft.com%2faccesscontrolservice%2f2010%2f07%2fclaims%2fidentityprovider=https%3a%2f%2fdatamarket.accesscontrol.windows.net%2f&Audience=http%3a%2f%2fapi.microsofttranslator.com&ExpiresOn=1381128612&Issuer=https%3a%2f%2fdatamarket.accesscontrol.windows.net%2f&HMACSHA256=Mw41PMMgw2n6ZVaGRXtwfR0vwMJUyIMltIyd9pa9MqA%3d
SOAPAction: "http://api.microsofttranslator.com/V2/LanguageService/Translate"
Content-Type: text/xml;charset=UTF-8
Content-Length: 454

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="http://tempuri.org/" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Body>
<wsdl:Translate>
<to>en</to>
<text>Это текст для перевода</text>
<category>general</category>
<contentType>text/html</contentType>
<from>ru</from>
</wsdl:Translate>
</env:Body>
</env:Envelope>
可能出了什么问题?任何已经使用Bing Translator SOAP API来区分我的SOAP消息的人都可以吗?关于如何解决此问题的任何建议

谢谢你的关注

编辑:

我已经用SoapUI检查了API,正如@SteffenRoller建议的那样,它是有效的。以下是通过手动插入SoapUI值生成的XML:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v2="http://api.microsofttranslator.com/V2">
   <soapenv:Header/>
   <soapenv:Body>
      <v2:Translate>
         <!--Optional:-->
         <v2:text>Текст, который я хочу перевести</v2:text>
         <!--Optional:-->
         <v2:from>ru</v2:from>
         <!--Optional:-->
         <v2:to>en</v2:to>
         <!--Optional:-->
         <v2:contentType>text/plain</v2:contentType>
         <!--Optional:-->
         <v2:category>general</v2:category>
      </v2:Translate>
   </soapenv:Body>
</soapenv:Envelope>
正如您所看到的,唯一的区别是a中的所有标记都在v2名称空间中。在由Savon生成的XML中,这个名称空间根本不存在

所以,现在的问题是:如何指示Savon为消息体中的标记使用正确的名称空间


虽然我认为这是一个Savon bug,但我会将其提交给开发人员,因为SoapUI已经通过相同的WSDL生成了正确的XML,而Savon没有。这是一个已知的错误:。它与复合WSDL文件相关,在当前主要版本中不会修复:-

因此,在我们的例子中,我们需要告诉Savon,我们的名称空间是什么,它的名称是什么,只是为了将它与WSDL对齐,并将每个标记的名称与这个名称空间放在一起

正确的代码如下所示:

require 'savon'

access_token = "http%3a%2f%2fschemas.xmlsoap.org%2fws...CA9TEs%3d"

client = Savon.client(
  wsdl: 'http://api.microsofttranslator.com/V2/soap.svc?wsdl',
  namespace: 'http://api.microsofttranslator.com/V2',
  namespace_identifier: :v2,
  headers: {'Authorization' => "Bearer #{access_token}"},
)

params = {
  'v2:text'        => 'Это текст для перевода',
  'v2:from'        => 'ru',
  'v2:to'          => 'en',
  'v2:contentType' => 'text/plain',
  'v2:category'    => 'general',
}

result = client.call(:translate, message: params)

puts result.body[:translate_response][:translate_result]

欢迎提供任何建议和更正。谢谢。

您试用过SoapUI吗?它起作用了吗?首先让它与SoapUI一起工作。在Ruby/Savon的第二步中实现它。@SteffenRoller,谢谢你的建议。它在SoapUI中工作,但XML不同,请参见更新的问题。
require 'savon'

access_token = "http%3a%2f%2fschemas.xmlsoap.org%2fws...CA9TEs%3d"

client = Savon.client(
  wsdl: 'http://api.microsofttranslator.com/V2/soap.svc?wsdl',
  namespace: 'http://api.microsofttranslator.com/V2',
  namespace_identifier: :v2,
  headers: {'Authorization' => "Bearer #{access_token}"},
)

params = {
  'v2:text'        => 'Это текст для перевода',
  'v2:from'        => 'ru',
  'v2:to'          => 'en',
  'v2:contentType' => 'text/plain',
  'v2:category'    => 'general',
}

result = client.call(:translate, message: params)

puts result.body[:translate_response][:translate_result]