为何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
相关产品推荐
相关产品推荐

