Python ElementTree从零创建写入XML时根标签自闭合问题
问题核心
使用Python标准库xml.etree.ElementTree生成XML文件时,无内容的根节点默认输出为自闭合标签<root />,预期输出为成对标签<root></root>。
原有实现代码:
root = ET.Element('root') tree = ET.ElementTree() tree._setroot(root) for items in dataList: temp = ET.Element('element') temp.set('attr_1', 'val') temp.set('attr_2', 'val') temp.set('attr_3', 'val') temp.set('attr_4', 'val' + Val) temp.set('attr_5', 'val' + items) tree.getroot().append(temp) tree.write('filename', encoding='unicode')
根因分析
xml.etree.ElementTree内置的序列化逻辑默认规则:
- 当元素的
text属性为None、且没有任何子节点时,会自动渲染为自闭合标签格式 - 如果运行时
dataList非空,根节点下成功挂载子节点,根标签本身不会变成自闭合形式,出现该问题首先可以排查执行写入时dataList是否为空 - 无论根节点下是否有子节点,只要需要强制空标签输出为成对开闭合格式,不需要修改序列化器或者换第三方库,用标准库本身的属性设置即可实现
修复方案
在创建根节点后,显式给根节点的text属性赋值为空字符串,即可强制序列化时输出成对标签。同时优化原有代码里的非官方写法,修复后可直接运行的核心代码如下:
import xml.etree.ElementTree as ET root = ET.Element('root') # 新增本行:强制空根节点输出成对的开/闭合标签 root.text = '' # 替换原私有方法_setroot的调用,使用官方公开的构造方法传入根节点 tree = ET.ElementTree(root) for items in dataList: temp = ET.Element('element') temp.set('attr_1', 'val') temp.set('attr_2', 'val') temp.set('attr_3', 'val') temp.set('attr_4', 'val' + Val) temp.set('attr_5', 'val' + items) # 直接操作root对象追加子节点即可,无需反复调用tree.getroot() root.append(temp) # 如需输出标准XML声明,可增加xml_declaration=True参数 tree.write('filename', encoding='unicode', xml_declaration=True)
- 该方案无第三方依赖,完全基于标准库实现,兼容所有Python3版本
- 其他需要输出成对标签的空元素,同样可以通过设置
元素对象.text = ''实现 - 原代码中调用的
_setroot是类的私有方法,不属于公开API,跨版本可能出现兼容性问题,直接在ElementTree构造函数传入根节点是官方文档推荐的标准写法
内容的提问来源于stack exchange,提问作者Zyga Sovan
相关产品推荐
相关产品推荐

