python suds在SOAP请求中错误的名称空间前缀

al_*_*iro 5 python xsd soap wsdl suds

我使用python/suds来实现一个客户端,我在发送的SOAP头中得到错误的名称空间前缀,用于element ref=wsdl中定义的特定参数类型.

.wsdl引用了数据类型.xsd文件,如下所示.问题在于函数GetRecordAttributes及其第一个类型参数gbt:recordReferences.

文件:browse2.wsdl

<xsd:schema targetNamespace="http://www.grantadesign.com/10/10/Browse" xmlns="http://www.grantadesign.com/10/10/Browse" xmlns:gbt="http://www.grantadesign.com/10/10/GrantaBaseTypes" elementFormDefault="qualified" attributeFormDefault="qualified">
<xsd:import schemaLocation="grantabasetypes2.xsd" namespace="http://www.grantadesign.com/10/10/GrantaBaseTypes"/>
<xsd:element name="GetRecordAttributes">
      <xsd:complexType>
          <xsd:sequence>
              <xsd:element ref="gbt:recordReferences">
              </xsd:element>
Run Code Online (Sandbox Code Playgroud)

引用文件:grantabasetypes2.xsd

<element name="recordReferences">
  <complexType>
    <sequence>
      <element name="record" minOccurs="0" maxOccurs="unbounded" type="gbt:MIRecordReference"/>
    </sequence>
  </complexType>
</element>
Run Code Online (Sandbox Code Playgroud)

suds发送的SOAP请求:

<SOAP-ENV:Envelope xmlns:ns0="http://www.grantadesign.com/10/10/GrantaBaseTypes" xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns2="http://www.grantadesign.com/10/10/Browse" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <ns1:Body>
      <ns2:GetRecordAttributes>
         <ns2:recordReferences>
            <ns0:record>
            </ns0:record>
         </ns2:recordReferences>
      </ns2:GetRecordAttributes>
   </ns1:Body>
</SOAP-ENV:Envelope>
Run Code Online (Sandbox Code Playgroud)

问题: <ns2:recordReferences>前缀错误,应该是 <ns0:recordReferences>因为它属于...GrantaBaseTypes .xsd中定义的命名空间.

这适用ref=于wsdl中定义的所有参数.如何自动修复?

注意:我通过curl手动发送xml SOAP请求,检查了服务是否接受了"good"前缀.

UPDATE

我使用SUDS源代码进行干预,并且以下经验修复强制所有带ref=属性的元素都假定引用的命名空间(以前,它们采用模式根命名空间或其他任何东西tns):

文件:/suds/xsd/sxbase.py

class SchemaObject(object):
....
    def namespace(self, prefix=None):

        ns = self.schema.tns

#FIX BEGIN
        if self.ref and self.ref in self.schema.elements.keys():
            ns = self.ref
#FIX END
Run Code Online (Sandbox Code Playgroud)

适用于我的服务,但我不确定它是否会破坏其他东西.我更喜欢更智能的解决方案,它不会改变SUDS源代码.

谢谢,

亚历克斯

dus*_*san 8

编写一个Suds插件,在发送之前修改XML.

from suds.client import Client
from suds.plugin import MessagePlugin

class MyPlugin(MessagePlugin):
    def marshalled(self, context):
        #modify this line to reliably find the "recordReferences" element
        context.envelope[1][0][0].setPrefix('ns0')

client = Client(WSDL_URL, plugins=[MyPlugin()])
Run Code Online (Sandbox Code Playgroud)

引用Suds文档:

marshalled()
为插件提供在发送之前检查/修改信封Document的机会.