使用Python Zeep调用SOAP接口构建QueryTypeCriteria对象报错求助
问题
尝试用Python Zeep模块发送SOAP请求,代码如下:
from zeep import Client url = 'localhost:8081/ws/?wsdl' def smev_grr(): client = Client(url) itSystem = '00000000' nodeId = 'my_node' factory = client.type_factory('ns1') specificQuery = client.get_type('ns1:QueryTypeCriteria') with client.settings(): response = client.service.Get(itSystem, nodeId, specificQuery('messageTypeCriteria')) print(response.text)
运行后出现错误:
zeep.exceptions.Fault: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 286; cvc-complex-type.2.4.b: The content of element 'specificQuery' is not complete. One of '{"urn://x-artefacts-smev-gov-ru/services/service-adapter/types":messageTypeCriteria}' is expected.
执行print(client.wsdl.dump())得到WSDL核心信息(截取关键部分):
Prefixes: ns1: urn://x-artefacts-smev-gov-ru/services/service-adapter/types Global types: ... ns1:QueryTypeCriteria(messageTypeCriteria: ns1:TypeCriteria) ns1:TypeCriteria ... Service: SMEVServiceAdapterService Port: SMEVServiceAdapterEndpoint (Soap11Binding: {urn://x-artefacts-smev-gov-ru/services/service-adapter}SMEVServiceAdapterEndpointBinding) Operations: Get(itSystem: xsd:string, nodeId: xsd:string, specificQuery: ns1:QueryTypeCriteria) -> smevMetadata: ns1:SmevMetadata, Message: ns1:Message
不清楚如何用factory和get_type正确构建所需对象。
解决方案
错误原因
从WSDL定义可知,QueryTypeCriteria类型要求必须包含messageTypeCriteria字段,且该字段的类型是ns1:TypeCriteria。之前的代码直接传入字符串'messageTypeCriteria',没有正确构造TypeCriteria实例,导致SOAP请求的XML结构不符合服务端验证规则。
正确构造对象的两种方式
方式一:使用get_type方法
from zeep import Client url = 'localhost:8081/ws/?wsdl' def smev_grr(): client = Client(url) itSystem = '00000000' nodeId = 'my_node' # 获取TypeCriteria和QueryTypeCriteria的类型构造器 type_criteria = client.get_type('ns1:TypeCriteria') query_criteria = client.get_type('ns1:QueryTypeCriteria') # 构造TypeCriteria实例,传入你需要的请求类型值 message_type = type_criteria('你的目标请求类型') # 构造QueryTypeCriteria实例,指定messageTypeCriteria参数 specific_query = query_criteria(messageTypeCriteria=message_type) with client.settings(): response = client.service.Get(itSystem, nodeId, specific_query) # 根据返回结构打印结果,示例如下 print("SmevMetadata:", response.smevMetadata) print("Message:", response.Message)
方式二:使用type_factory方法
from zeep import Client url = 'localhost:8081/ws/?wsdl' def smev_grr(): client = Client(url) itSystem = '00000000' nodeId = 'my_node' # 获取ns1命名空间的类型工厂 factory = client.type_factory('ns1') # 构造TypeCriteria实例 message_type = factory.TypeCriteria('你的目标请求类型') # 构造QueryTypeCriteria实例 specific_query = factory.QueryTypeCriteria(messageTypeCriteria=message_type) with client.settings(): response = client.service.Get(itSystem, nodeId, specific_query) print("SmevMetadata:", response.smevMetadata) print("Message:", response.Message)
说明
- 两种方式本质都是先创建
TypeCriteria实例(传入实际的请求类型值),再将其作为messageTypeCriteria参数传入QueryTypeCriteria的构造器,生成符合WSDL要求的对象。 - 注意替换代码中的
'你的目标请求类型'为实际需要查询的消息类型字符串。 - 返回结果的打印方式需根据服务端实际返回的结构调整,示例中使用
response.smevMetadata和response.Message是参考WSDL中Get方法的返回定义。
内容的提问来源于stack exchange,提问作者lomach
相关产品推荐
相关产品推荐

