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源代码.
谢谢,
亚历克斯
编写一个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的机会.