我有供应商提供的Web服务;特定操作的WSDL如下所示:

<complexType name="ArrayOf_soapenc_string">
 <complexContent>
  <restriction base="soapenc:Array">
   <attribute ref="soapenc:arrayType" wsdl:arrayType="soapenc:string[]"/>
  </restriction>
 </complexContent>
</complexType>
...
<wsdl:message name="initExportDeviceRequest">
 <wsdl:part name="filter" type="soapenc:string"/>
 <wsdl:part name="options" type="impl:ArrayOf_soapenc_string"/>
</wsdl:message>
...
<wsdl:operation name="initExportDevice" parameterOrder="filter options">
 <wsdl:input message="impl:initExportDeviceRequest" name="initExportDeviceRequest"/>
 <wsdl:output message="impl:initExportDeviceResponse" name="initExportDeviceResponse"/>
</wsdl:operation>

在WSDL上运行python -mzeep ipam_export.wsdl会产生以下结果:
Global types:
 ns0:ArrayOf_soapenc_string(_value_1: string[], arrayType: xsd:string, offset: ns1:arrayCoordinate, id: xsd:ID, href: xsd:anyURI, _attr_1: {})
...
Service: ExportsService
 Port: Exports (Soap11Binding: {http://diamondip.com/netcontrol/ws/}ExportsSoapBinding)
  Operations:
   ...
   initExportDevice(filter: ns1:string, options: {_value_1: string[], arrayType: xsd:string, offset: ns1:arrayCoordinate, id: xsd:ID, href: xsd:anyURI, _attr_1: {}}) -> initExportDeviceReturn: ns2:WSContext

我在执行initExportDevice调用(特别是options参数)时遇到困难。

How to use a complex type from a WSDL with zeep in Python建议我这样做:
filter_type=client.get_type('ns1:string')
filter=filter_type('addrType=4')
options_type=client.get_type('ns0:ArrayOf_soapenc_string')
options=options_type(['recurseContainerHierarchy'])
client.service.initExportDevice(filter, options)

但它引发了一个异常(exception)
Any element received object of type 'str', expected lxml.etree._Element or zeep.objects.string
See http://docs.python-zeep.org/en/master/datastructures.html#any-objects for more information

任何
options_type=client.get_type('ns0:ArrayOf_soapenc_string')
options=options_type('recurseContainerHierarchy')
client.service.initExportDevice(filter, options)

或者
factory = client.type_factory('ns0')
options=factory.ArrayOf_soapenc_string(['recurseContainerHierarchy'])
client.service.initExportDevice(filter=filter, options=options)

或者
factory = client.type_factory('ns0')
options=factory.ArrayOf_soapenc_string('recurseContainerHierarchy')
client.service.initExportDevice(filter=filter, options=options)

或者
factory = client.type_factory('ns0')
options=factory.ArrayOf_soapenc_string(_value_1=['recurseContainerHierarchy'])
client.service.initExportDevice(filter=filter, options=options)

都引发相同的异常
options_type=client.get_type('ns0:ArrayOf_soapenc_string')
options=xsd.AnyObject(options_type, ['recurseContainerHierarchy'])
client.service.initExportDevice(filter, options)

产量
argument of type 'AnyObject' is not iterable

如何构造此参数?

最佳答案

好的,所以我在使用Zeep时也遇到了麻烦(很容易使用suds),问题是Zeep将数组作为函数返回(根据我的测试),因此您需要将函数分配给数组,然后对其进行修改。从您当前的代码来看,好像您是将数据直接传递给该函数(该函数不会存储数据)。

使用上面的示例,下面的示例应检索Array类型,并允许您将其修改为有效的数据类型。

emptyArrayPlaceholder = client.get_type('ns0:ArrayOf_soapenc_string')

然后,Zeep将这种类型作为函数返回,因此首先您需要将此函数分配给变量,例如:
options = emptyArrayPlaceholder()

如果随后要检查选项,您将看到它是字典,其中包含列表。
print (options)
{'soapenc': []}

然后,您可以使用以下命令轻松地将项目添加到数组中:
options['soapenc'].append('Foo')

然后,您应该可以向您的客户提交
client.service.initExportDevice(filter, options)

作为选项,现在是有效的Zeep数据类型。

关于python - 使用zeep创建字符串数组参数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42395599/

10-12 15:18