使用Spyne复刻SOAP服务时,如何建模无类型数组的ComplexModel
解决Spyne中未类型化数组的建模问题
我来帮你搞定这个Spyne复刻SOAP服务时的未类型化数组建模问题。从Suds的输出能看出,inquireRequest是个未定义类型的空数组,结合你已经继承TSYSRequestMsgType的前提,咱们可以按以下步骤正确建模:
1. 先确认WSDL的实际定义
首先建议你再核对下原始WSDL里inquireRequest的元素定义,这种“未类型化”数组通常对应WSDL里的xsd:anyType类型(支持容纳任意XML内容),典型的WSDL定义大概是这样:
<xsd:element name="inquireRequest" type="xsd:anyType" maxOccurs="unbounded"/>
如果是这种情况,后续的建模方向就很明确了。
2. 用Spyne的Array + AnyXml组合建模
Spyne提供了AnyXml类型来处理任意XML内容,搭配Array就能实现未类型化数组的定义。修改你的TSYSMultipleInquiryRequestType类如下:
from spyne import ComplexModel, Unicode, Array, AnyXml class TSYSMultipleInquiryRequestType(TSYSRequestMsgType): # 必须设置和原始WSDL完全一致的命名空间 __namespace__ = "你的WSDL命名空间" reqID = Unicode(values_pattern=r".*") # 对应输出中的_reqID字段 # 用Array包裹AnyXml来定义未类型化数组 inquireRequest = Array(AnyXml)
3. 关键注意事项
- 命名空间匹配:
__namespace__必须和原始WSDL中该类型的命名空间完全一致,否则Suds客户端解析时会出现类型不匹配的问题。 - 字段名一致性:类中的
inquireRequest字段名要和WSDL里的元素名完全对应,这样Suds才能正确映射字段。
4. 测试验证
定义完成后启动Spyne服务,用Suds客户端重新生成请求对象并测试:
from suds.client import Client # 替换成你的服务WSDL地址 client = Client("http://localhost:8000/your_service?wsdl") # 创建请求对象 req = client.factory.create("TSYSMultipleInquiryRequestType") req._reqID = "TEST_REQ_001" # 向未类型化数组中添加任意XML内容 req.inquireRequest.append("<SampleRequest><UserId>123</UserId><Query>test</Query></SampleRequest>") # 打印验证结果 print(req)
这时你应该能看到inquireRequest数组中已经包含了你添加的元素,不再是<empty>状态。
如果你的WSDL中inquireRequest其实是某个抽象基类的数组(而非完全无类型),可以把AnyXml替换成对应的基类类型,比如Array(TSYSRequestMsgType),但根据你描述的情况,Array(AnyXml)应该是最适配的方案。
内容的提问来源于stack exchange,提问作者Divick
相关产品推荐
相关产品推荐

