使用zeep / python创建XML序列
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用zeep / python创建XML序列相关的知识,希望对你有一定的参考价值。
我使用zeep(Python 3.6)与SOAP API接口,并使用包含此部分的WSDL架构:
<xs:element name="passengers">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="passenger" type="com:PassengerType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
所以我希望我的zeep生成的XML看起来像这样:
<book:passengers>
<book:passenger>
...redacted...
</book:passenger>
</book:passengers>
我用Zeep实现这一目标的第一次尝试看起来像这样:
passengers = [factories.PassengerType()]
但是,将此发送到我的SOAP API时,会产生以下错误:
File "/usr/local/lib/python3.6/site-packages/zeep/xsd/elements/element.py", line 220, in validate
"Missing element %s" % (self.name), path=render_path)
zeep.exceptions.ValidationError: Missing element passenger (createBookingRecordRequest.passengers)
我相信这是因为我的'passenger'属性应该包含一个标签名为“passenger”的Zeep对象,它将包含我的元素列表。我试图修补zeep.xsd.AnyType
来实现这一目标,但还没有成功。
任何建议,将不胜感激。
回答我自己的问题,因为我现在已经解决了,并没有收到任何其他答案。
这个问题的根源在于我正在尝试创建未通过SOAP API的WSDL显式定义为类型的XML元素。这是可以的,因为Zeep仍然会为它生成类型对象,它只是不会将这些类型分配给特定的名称,所以我们必须跳过一些额外的箍来获得这些类型。这就是我花了一点时间才弄清楚的。
您可以通过任何父类型访问这些对象来获取这些对象。它们存储在名为elements
的属性中,作为2元组的列表。在这种情况下,我的PassengerType
对象应该由具有属性名称“passengers”的序列容器包含。例如,如果我的父类型名为ParentType
,我可以像这样使用“乘客”序列:
passengers = dict(ParentType.elements)['passengers'](
PassengerType(),
...
PassengerType()
)
在这里,我们将元素对象转换为dict(利用它是一个2元组的列表,其中第一个项是属性名称的字符串),然后按名称拉出元素。
生成的对象可以直接传递到ParentType
,如:
ParentType(passengers=passengers)
简单。
我发现的另一个替代方法是使用zeep的xsd
对象显式构建类型。示例如下所示。
from lxml import etree
from zeep import xsd
PassengersType = xsd.ComplexType(
xsd.Sequence([
xsd.Element('passengers', PassengerType, min_occurs=1, max_occurs='unbounded')
]), qname=etree.QName("{http://example.com/schema}passengers")
)
我认为这不是很好,但可能对登陆这里的人有用。
以上是关于使用zeep / python创建XML序列的主要内容,如果未能解决你的问题,请参考以下文章
我需要创建一个使用 ZEEP 或 REQUEST 模块调用 SOAP GET 方法的 python 脚本
带有zeep的python SOAP,requests.exception:403客户端错误
[TimLinux] Python3 Coverity zeep/SOAP 库使用示例