Zeep SOAP请求中如何处理WSDL的Any类型?
<xs:complexType name="hilfsmittelattribute">
xs:sequence
<xs:any maxOccurs="unbounded" namespace="http://hma.ws.bswsnt.vsa/xsd" processContents="skip"/>
</xs:sequence>
</xs:complexType>
...
## 我期望实现的调用方式: ```python conn = zeep.Client(...) data = { .... 'hilfsmittelattribute': {'koerperhaelfte': 1} ... } pack = conn.service.someMethod(**data)
遇到的错误:
TypeError: ... got an unexpected keyword argument 'koerperhaelfte'. Signature: `_value_1: ANY[]`
尝试过程中的问题:
- 执行
conn.get_element('ns0:hilfsmittelattribute')(或ns1/ns2/ns3等)时,返回错误:
LookupError: No element 'hilfsmittelattribute' in namespace http://ws.bswsnt.vsa/xsd. Available elements are: -
- 执行
hilfsmittelattribute_type = conn.get_type('ns2:hilfsmittelattribute')可获取类型对象,其元素为:
hilfsmittelattribute_type.elements >> [('_value_1', <Any(name=None)>)]
- 尝试如下方式使用类型对象:
hilfsmittelattribute_ = xsd.AnyObject( hilfsmittelattribute_type, hilfsmittelattribute_type(koerperhaelfte='1'))
依然报错:
TypeError: {...}hilfsmittelattribute() got an unexpected keyword argument 'koerperhaelfte'. Signature: `_value_1: ANY[]`
补充信息:
手动构造SOAP信封如下时,请求可正常工作:
.... <hilfsmittelattribute> <koerperhaelfte>5</koerperhaelfte> </hilfsmittelattribute> ....
问题出在Zeep对Any类型的处理逻辑上。
解决方法
由于WSDL中hilfsmittelattribute类型包含<xs:any>元素,Zeep会将其映射为_value_1: ANY[]结构,不能直接传入键值对,需构造符合要求的Any对象列表:
方法1:通过Zeep的xsd.Element构造
from zeep import xsd # 从conn.namespaces中找到对应命名空间的前缀,假设目标命名空间映射为'ns_hma' ns_hma = conn.namespaces['http://hma.ws.bswsnt.vsa/xsd'] # 构造koerperhaelfte元素 koerperhaelfte_elem = xsd.Element( f'{ns_hma}:koerperhaelfte', xsd.SimpleType(xsd.String()) )(value='1') # 生成hilfsmittelattribute实例,传入Any对象列表 hilfsmittel_attr = hilfsmittelattribute_type( _value_1=[xsd.AnyObject(koerperhaelfte_elem, '1')] ) # 调用接口 data = { # ...其他参数... 'hilfsmittelattribute': hilfsmittel_attr } pack = conn.service.someMethod(**data)
方法2:直接构造XML元素
from lxml import etree from zeep import xsd # 构造带命名空间的XML元素 elem = etree.fromstring(''' <koerperhaelfte xmlns="http://hma.ws.bswsnt.vsa/xsd">1</koerperhaelfte> ''') # 生成hilfsmittelattribute实例 hilfsmittel_attr = hilfsmittelattribute_type( _value_1=[xsd.AnyObject(elem, elem)] ) # 调用接口 data = { # ...其他参数... 'hilfsmittelattribute': hilfsmittel_attr } pack = conn.service.someMethod(**data)
原理:Zeep要求<xs:any>对应的参数是Any对象的列表,需要将自定义元素包装成xsd.AnyObject后放入_value_1列表,这样就能生成与手动构造一致的SOAP信封结构。
内容的提问来源于stack exchange,提问作者Marko Zadravec
相关产品推荐
相关产品推荐

