Odoo15使用Python Requests提交ElementTree生成的XML报错问题
问题原因
返回报错核心信息:
faultstring: "Cannot create SOAP envelope from: ClaimBatch"
该报错的核心原因是SOAP接口有固定的报文结构要求,你直接把业务根节点<ClaimBatch>作为请求体发送,没有包裹标准SOAP协议要求的Envelope外层结构,服务端无法解析出合法的SOAP信封,直接抛出服务端错误。
现有代码存在两个直接触发错误的问题:
- 未构造SOAP标准的
Envelope -> Header -> Body层级结构,直接发送裸业务XML - 发送POST请求时未指定XML对应的
Content-Type请求头,部分SOAP服务会因请求头不合法直接拒绝请求
修复步骤
- 保留你原有构造
<ClaimBatch>业务节点的全部逻辑,在发送请求前额外构造标准SOAP外层结构,将业务节点挂载到Body节点下 - 请求头中添加正确的
Content-Type标识,序列化XML时输出标准XML声明
替换原有请求发送部分的代码即可:
# ----- 以下为新增SOAP信封构造逻辑,放在你构造完Transaction(ClaimBatch)节点之后 ----- # 定义SOAP标准命名空间 SOAP_NS = "http://schemas.xmlsoap.org/soap/envelope/" # 构造Envelope根节点 soap_env = etree.Element(f"{{{SOAP_NS}}}Envelope", nsmap={"env": SOAP_NS}) # 构造空Header节点,匹配返回值中env:Header为null的要求 etree.SubElement(soap_env, f"{{{SOAP_NS}}}Header") # 构造Body节点,挂载业务根节点 soap_body = etree.SubElement(soap_env, f"{{{SOAP_NS}}}Body") soap_body.append(Transaction) # ----- 替换原有requests.post请求逻辑 ----- headers = {"Content-Type": "text/xml; charset=utf-8"} # 序列化时加上xml_declaration参数,输出符合规范的带声明XML报文 request_data = ET.tostring(soap_env, encoding="utf-8", xml_declaration=True) send_xml_data = requests.post( url, data=request_data, headers=headers, verify=False ).text # 注:原代码中respose为拼写错误,正确写法为response,可自行修正避免后续维护问题 respose = xmltodict.parse(send_xml_data) set_json = json.dumps(respose) self.error_msg = set_json
额外注意事项
- 你当前构造的
batchDate、transactionType、testClaim、numClaims节点均为空值,修复结构问题后请确认业务侧是否允许空值传参,避免触发业务校验报错 - 如果调整结构后仍收到SOAP错误,可在请求头中补充
SOAPAction字段,字段值可从对接的WSDL文件中对应接口定义处获取
内容的提问来源于stack exchange,提问作者imbra
相关产品推荐
相关产品推荐

