如何用Python ElementTree创建带指定命名空间的XML子元素ISAddSegments
解决Python ElementTree生成默认命名空间SOAP请求的问题
你遇到的问题是ElementTree自动给ISAddSegments元素分配了ns1前缀,而你想要的是把这个命名空间设为默认命名空间(即不带前缀,通过xmlns="..."声明在元素上)。下面是具体的解决方法:
关键要点
要让ISAddSegments使用默认命名空间,需要:
- 注册空前缀(对应默认命名空间)的目标URI
- 子元素会自动继承父元素的默认命名空间,无需额外指定命名空间前缀
修正后的完整代码
import xml.etree.ElementTree as ET # 注册SOAP信封的命名空间 ET.register_namespace('soapenv', 'http://www.w3.org/2003/05/soap-envelope') # 注册默认命名空间(空前缀)对应你的业务接口URI ET.register_namespace('', 'http://www.blue-order.com/ma/integrationservicews/api') # 创建根元素Envelope envelope = ET.Element("{http://www.w3.org/2003/05/soap-envelope}Envelope") body = ET.SubElement(envelope, '{http://www.w3.org/2003/05/soap-envelope}Body') # 创建ISAddSegments元素(使用默认命名空间的URI) is_add_segments = ET.SubElement(body, '{http://www.blue-order.com/ma/integrationservicews/api}ISAddSegments') # 添加子元素,继承父元素的默认命名空间,直接用标签名即可 access_key = ET.SubElement(is_add_segments, 'accessKey') access_key.text = 'key' object_id = ET.SubElement(is_add_segments, 'objectID') guid = ET.SubElement(object_id, 'guid') guid.text = 'guid' stratum_name = ET.SubElement(is_add_segments, 'StratumName') stratum_name.text = 'STRATUM' segments = ET.SubElement(is_add_segments, 'Segments') segment = ET.SubElement(segments, 'Segment') begin = ET.SubElement(segment, 'Begin') begin.text = '00:00:00:00' content = ET.SubElement(segment, 'Content') content.text = 'TEXT' end = ET.SubElement(segment, 'End') end.text = '00:00:10:00' # 格式化并输出XML(Python 3.9+支持indent方法做格式化) ET.indent(envelope) tree = ET.ElementTree(envelope) tree.write('output.xml', encoding='UTF-8', xml_declaration=True) # 直接打印输出的方式 import io output_buffer = io.BytesIO() tree.write(output_buffer, encoding='UTF-8', xml_declaration=True) print(output_buffer.getvalue().decode('UTF-8'))
为什么原来的代码会生成ns1前缀?
原来的代码只注册了soapenv命名空间,但没有把你的业务接口URI注册为默认命名空间。ElementTree遇到未注册的命名空间URI时,会自动生成类似ns1的前缀来标识它,这就是你看到额外命名空间的原因。
通过ET.register_namespace('', 'http://www.blue-order.com/ma/integrationservicews/api')注册空前缀后,ElementTree就会把这个URI作为默认命名空间,在ISAddSegments元素上通过xmlns="..."声明,而不是生成前缀。
最终生成的XML效果
运行上述代码后,会生成你需要的目标格式:
<?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns="http://www.blue-order.com/ma/integrationservicews/api"> <soapenv:Body> <ISAddSegments> <accessKey>key</accessKey> <objectID> <guid>guid</guid> </objectID> <StratumName>STRATUM</StratumName> <Segments> <Segment> <Begin>00:00:00:00</Begin> <Content>TEXT</Content> <End>00:00:10:00</End> </Segment> </Segments> </ISAddSegments> </soapenv:Body> </soapenv:Envelope>
内容的提问来源于stack exchange,提问作者user2811144
相关产品推荐
相关产品推荐

