如何使用Python去除XML文档冗余空白以生成紧凑对齐的XML格式?
解决XML去除冗余空白但保留元素间空格的问题
看来你想要的是去除XML中多余的换行、缩进等冗余空白,但保留元素标签之间的单个空格,同时不把整个文档压缩成完全无间隔的一行,对吧?我来给你几个可行的方案:
方法一:直接用ElementTree生成紧凑格式(推荐)
既然你的XML是用ElementTree创建的,那直接用ET.tostring()生成紧凑格式就最方便了,它默认会保留元素间的单个空格,不会生成多余的缩进或换行:
import xml.etree.ElementTree as ET # 假设root是你已经构建好的根元素 # 生成紧凑的XML字节流,指定编码和method='xml' xml_bytes = ET.tostring(root, encoding='utf-8', method='xml') # 转成字符串 xml_string = xml_bytes.decode('utf-8') # 如果你需要自定义XML声明的encoding(比如替换成你的m_encoding变量) if '<?xml' in xml_string: # 拆分声明和内容部分 decl_part, content_part = xml_string.split('?>', 1) # 重新拼接成指定编码的声明 xml_string = f"{decl_part}encoding=\"{m_encoding}\"?>{content_part}" # 写入文件 with open("MyXml.xml", 'w', encoding='utf-8') as xfile: xfile.write(xml_string)
这个方法生成的XML会完全符合你的预期:没有冗余空白,元素之间保留单个空格,同时不会把所有内容挤成完全连在一起的一行。
方法二:用minidom清理空白后调整格式
如果你一定要用minidom处理,那需要先清理掉所有无用的空白文本节点,再调整输出格式:
import xml.dom.minidom as minidom import xml.etree.ElementTree as ET import re def clean_empty_text_nodes(node): """清理XML中所有空的文本节点(只含空白的节点)""" for child in list(node.childNodes): if child.nodeType == minidom.Node.TEXT_NODE: if not child.data.strip(): node.removeChild(child) else: # 如果是有效文本,保留正常空格(比如你<h1>里的内容) child.data = ' '.join(child.data.split()) elif child.nodeType == minidom.Node.ELEMENT_NODE: clean_empty_text_nodes(child) # 从ElementTree的root转成minidom对象 dom = minidom.parseString(ET.tostring(root)) # 清理空白节点 clean_empty_text_nodes(dom.documentElement) # 生成XML字符串 xml_string = dom.toxml() # 调整声明的encoding decl_part, content_part = xml_string.split('?>', 1) xml_string = f"{decl_part}encoding=\"{m_encoding}\"?>{content_part}" # 把元素之间的多余空白替换成单个空格(避免完全挤成一行) xml_string = re.sub(r'>\s+<', '> <', xml_string) # 写入文件 with open("MyXml.xml", 'w', encoding='utf-8') as xfile: xfile.write(xml_string)
为什么你之前的方法没生效?
- 你用
writexml(indent="", addindent="", newl="")会把所有内容压缩成完全无间隔的一行,因为它去掉了所有换行和空格,不符合你的需求。 - 用
toprettyxml()会生成带缩进的格式化XML,反而增加了冗余空白。 - 你最新的
split("\n")然后strip()的方法,虽然去掉了换行,但没处理元素之间的多余空格,而且可能会误删文本内容里的必要空格。
内容的提问来源于stack exchange,提问作者John




