You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Python ElementTree解析后tostring输出保留换行与空格?

问题原因与解决方案

核心原因并非expat解析器的问题,而是xml.etree.ElementTree的默认行为:解析时会保留输入XML中的空白文本节点(包括缩进、换行这类仅含空白的内容),因此两个文件解析后的DOM树结构存在差异(一个包含空白节点,一个没有),调用tostring()时自然会输出和输入一致的格式。

解决方案1:解析时忽略空白节点

解析XML时,创建指定strip_space=True的XML解析器,让解析器自动忽略仅含空白的文本节点,这样两个文件解析后的DOM树结构完全一致,输出格式就统一了:

import xml.etree.ElementTree as ET

# 创建忽略空白的解析器
parser = ET.XMLParser(strip_space=True)

# 解析两个文件
tree_indented = ET.parse('indented.xml', parser=parser)
tree_oneline = ET.parse('oneline.xml', parser=parser)

# 输出统一格式的XML内容
print(ET.tostring(tree_indented.getroot(), encoding='utf-8').decode())
print(ET.tostring(tree_oneline.getroot(), encoding='utf-8').decode())

解决方案2:手动格式化输出(带缩进)

如果需要输出带缩进的格式化XML,可以自己实现一个缩进函数,对解析后的根节点进行处理后再调用tostring():

import xml.etree.ElementTree as ET

def indent(elem, level=0):
    indent_str = "\n" + level * "  "
    if len(elem):
        # 处理子节点前的文本缩进
        if not elem.text or not elem.text.strip():
            elem.text = indent_str + "  "
        # 处理当前节点后的文本缩进
        if not elem.tail or not elem.tail.strip():
            elem.tail = indent_str
        # 递归处理子节点
        for child in elem:
            indent(child, level + 1)
        # 处理最后一个子节点的尾部缩进
        if not child.tail or not child.tail.strip():
            child.tail = indent_str
    else:
        # 处理叶子节点的尾部缩进
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = indent_str

# 解析文件(可选使用strip_space)
tree = ET.parse('oneline.xml')
root = tree.getroot()

# 添加缩进格式
indent(root)

# 输出格式化后的XML
print(ET.tostring(root, encoding='utf-8').decode())

内容的提问来源于stack exchange,提问作者Steffen Rheinhold

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 02:30:59