使用SUDS时添加xsi:type和envelope命名空间

时间:2012-06-06 14:36:32

标签: python xml soap wsdl suds

我需要与SOAP服务进行交互,并且这样做很麻烦;我真的很感激任何指针。原始错误消息是:

org.apache.axis2.databinding.ADBException: Any type element type has not been given
经过一番研究,结果证明这是SUDS与服务器之间的分歧,如何应对

type="xsd:anyType"

关于相关元素。

我已经确认使用SOAPUI,并在建议后可以通过以下步骤解决问题:

  1. 将xsi:type =“xsd:string”添加到导致问题的每个元素
  2. 将xmlns:xsd =“http://www.w3.org/2001/XMLSchema”添加到SOAP信封
  3. 所以,SUDS目前这样做:

    <SOAP-ENV:Envelope ... xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <ns3:Body>
      <ns0:method>
         <parameter>
            <values>
               <table>
                  <key>EMAIL_ADDRESS</key>
                  <value>example@example.org</value>
               </table>
            </values>
         </parameter>
      </ns0:method>
    

           

    它应该产生这个:

    <SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" ... xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    
      <ns3:Body>
      <ns0:method>
         ...
         <parameter>
            <values>
               <table>
                  <key xsi:type="xsd:string">EMAIL_ADDRESS</key>
                  <value xsi:type="xsd:string">example@example.org</value>
               </table>
            </values>
         </parameter>
      </ns0:method>
    

    有没有正确的方法呢?我已经看到了使用ImportDoctor或MessagePlugins的建议,但还没有真正了解如何达到预期的效果。

2 个答案:

答案 0 :(得分:10)

我发现的解决方案是使用MessagePlugin在发送之前基本上手动修复XML。我希望有更优雅的东西,但至少这有用:

class SoapFixer(MessagePlugin):

    def marshalled(self, context):
        # Alter the envelope so that the xsd namespace is allowed
        context.envelope.nsprefixes['xsd'] = 'http://www.w3.org/2001/XMLSchema'
        # Go through every node in the document and apply the fix function to patch up incompatible XML. 
        context.envelope.walk(self.fix_any_type_string)

    def fix_any_type_string(self, element):
        """Used as a filter function with walk in order to fix errors.
        If the element has a certain name, give it a xsi:type=xsd:string. Note that the nsprefix xsd must also
         be added in to make this work."""
        # Fix elements which have these names
        fix_names = ['elementnametofix', 'anotherelementname']
        if element.name in fix_names:
            element.attributes.append(Attribute('xsi:type', 'xsd:string'))

答案 1 :(得分:1)

这很悲伤,很有趣,就像关于这个特定图书馆的很多事情一样,但这里的确切答案是:

http://lists.fedoraproject.org/pipermail/suds/2011-September/001519.html

来自上面:

soapenv = soapenv.encode('utf-8')
plugins.message.sending(envelope=soapenv)

变为:

soapenv = soapenv.encode('utf-8')
ctx = plugins.message.sending(envelope=soapenv)
soapenv = ctx.envelope

基本上,这是实现中的一个错误,您可以通过编辑运行该插件的行来自行修补它以实际返回插件的结果,但我不知道修补此修补程序的修补和更新版本的SUDS (我没有密切关注它)。