如何基于JSON请求体创建SOAP信封?寻求非硬编码方案
动态生成SOAP信封的替代方案
针对你需要从JSON请求体动态生成SOAP信封(避免硬编码XML)的需求,以下是几个实用的Python方案:
1. 用Python标准库xml.etree.ElementTree构建XML
无需额外安装依赖,完全用原生API构建XML结构,能灵活处理动态元素:
import xml.etree.ElementTree as ET from xml.dom import minidom def json_to_soap(json_data): # 定义命名空间 ns = { 'soapenv': 'http://schemas.xmlsoap.org/soap/envelope/', 'tem': 'http://tempuri.org/' } # 注册命名空间,避免输出前缀变成ns0 ET.register_namespace('soapenv', ns['soapenv']) ET.register_namespace('tem', ns['tem']) # 创建根元素Envelope envelope = ET.Element(f"{{{ns['soapenv']}}}Envelope") # 添加Header header = ET.SubElement(envelope, f"{{{ns['soapenv']}}}Header") # 创建Body body = ET.SubElement(envelope, f"{{{ns['soapenv']}}}Body") # 创建Download元素 download = ET.SubElement(body, f"{{{ns['tem']}}}Download") # 遍历JSON数据,动态添加子元素 for key, value in json_data.items(): # 确保key对应tem命名空间下的元素(比如ID2、ID等) elem = ET.SubElement(download, f"{{{ns['tem']}}}{key}") elem.text = str(value) # 格式化XML,让输出更易读 rough_string = ET.tostring(envelope, 'utf-8') reparsed = minidom.parseString(rough_string) return reparsed.toprettyxml(indent=" ") # 测试用JSON数据 sample_json = { "ID2": "1", "ID": "1", "CNO": "466", "Type": "01" } soap_envelope = json_to_soap(sample_json) print(soap_envelope)
2. 用xmltodict库实现JSON到XML的转换
xmltodict能简化JSON与XML的互转,适合结构匹配的场景:
首先安装依赖:
pip install xmltodict
然后编写转换代码:
import xmltodict def json_to_soap(json_data): # 构造符合SOAP结构的嵌套字典 soap_dict = { f"soapenv:Envelope": { "@xmlns:soapenv": "http://schemas.xmlsoap.org/soap/envelope/", "@xmlns:tem": "http://tempuri.org/", "soapenv:Header": None, "soapenv:Body": { "tem:Download": json_data } } } # 转换为XML字符串,添加声明并格式化 soap_envelope = xmltodict.unparse(soap_dict, pretty=True, encoding='utf-8') return soap_envelope.decode('utf-8') # 测试用JSON数据 sample_json = { "tem:ID2": "1", "tem:ID": "1", "tem:CNO": "466", "tem:Type": "01" } soap_envelope = json_to_soap(sample_json) print(soap_envelope)
3. 用Jinja2模板引擎渲染SOAP信封
如果SOAP结构相对固定,只是字段值动态变化,Jinja2模板会更直观:
首先安装依赖:
pip install jinja2
然后编写模板和渲染代码:
from jinja2 import Template # 定义SOAP模板 soap_template = Template(""" <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/"> <soapenv:Header/> <soapenv:Body> <tem:Download> {% for key, value in data.items() %} <tem:{{ key }}>{{ value }}</tem:{{ key }}> {% endfor %} </tem:Download> </soapenv:Body> </soapenv:Envelope> """) def json_to_soap(json_data): return soap_template.render(data=json_data) # 测试用JSON数据 sample_json = { "ID2": "1", "ID": "1", "CNO": "466", "Type": "01" } soap_envelope = json_to_soap(sample_json) print(soap_envelope.strip())
以上三种方案都能避免硬编码XML,根据你的实际场景选择:
- 追求原生无依赖选
ElementTree; - 追求快速开发选
xmltodict; - 结构固定、需要可读性选Jinja2模板。
内容的提问来源于stack exchange,提问作者Satyam Gupta
相关产品推荐
相关产品推荐

