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

Python XML添加元素时出现多余换行问题及解决方法

XML添加元素后出现多余换行的问题分析与修复

问题重现

执行以下Python代码向XML文件添加元素后,文件中出现了多余的换行:

from xml.dom import minidom
import xml.etree.ElementTree as ET

def example(name, category):
    tree = ET.parse("example1.xml")
    root = tree.getroot()

    for i in root:
        if i.tag == category:
            ET.SubElement(i, name).text = name

    xmlStr = minidom.parseString(ET.tostring(root)).toprettyxml(indent="    ")
    with open("example1.xml", "w") as f:
        f.write(xmlStr)

example("test", 'FRUITS')

原XML文件内容:

<?xml version="1.0" ?>
<root>
    <FRUITS>
        <APPLE>apple</APPLE>
        <PEAR>pear</PEAR>
        <PLUM>plum</PLUM>
    </FRUITS>
    <VEGETABLES>
        <CARROT>carrot</CARROT>
        <POTATO>potato</POTATO>
    </VEGETABLES>
</root>

问题成因

  1. 格式叠加冲突:ElementTree的tostring()方法输出的XML已经包含基础换行结构,而minidom的toprettyxml()会再次给所有节点插入换行和缩进,两者叠加后产生多余空行。
  2. minidom默认行为:toprettyxml()会自动处理所有文本节点,包括原XML中的空白文本节点,额外插入换行,导致空行数量增多。

修复方案

方案一:过滤多余空行

在写入文件前,过滤掉toprettyxml()生成的空行:

from xml.dom import minidom
import xml.etree.ElementTree as ET

def example(name, category):
    tree = ET.parse("example1.xml")
    root = tree.getroot()

    for i in root:
        if i.tag == category:
            ET.SubElement(i, name).text = name

    xmlStr = minidom.parseString(ET.tostring(root)).toprettyxml(indent="    ")
    # 过滤空行和仅含空白字符的行
    xmlStr = '\n'.join(line for line in xmlStr.split('\n') if line.strip())
    with open("example1.xml", "w") as f:
        f.write(xmlStr)

example("test", 'FRUITS')

方案二:使用ElementTree自带的indent方法(Python 3.9+)

Python 3.9及以上版本的ElementTree新增了indent()方法,无需依赖minidom,直接给XML树添加规范缩进:

import xml.etree.ElementTree as ET

def example(name, category):
    tree = ET.parse("example1.xml")
    root = tree.getroot()

    for i in root:
        if i.tag == category:
            ET.SubElement(i, name).text = name

    # 设置缩进为4个空格
    ET.indent(root, space="    ")
    # 写入文件时指定编码和XML声明
    tree.write("example1.xml", encoding="utf-8", xml_declaration=True)

example("test", 'FRUITS')

方案三:手动处理XML输出(兼容低版本Python)

如果使用Python 3.8及以下版本,可以手动构建带缩进的XML字符串,避免依赖minidom:

import xml.etree.ElementTree as ET

def indent(elem, level=0):
    indent_str = "    "
    i = "\n" + level * indent_str
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + indent_str
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        for elem in elem:
            indent(elem, level+1)
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i

def example(name, category):
    tree = ET.parse("example1.xml")
    root = tree.getroot()

    for i in root:
        if i.tag == category:
            ET.SubElement(i, name).text = name

    # 手动添加缩进
    indent(root)
    tree.write("example1.xml", encoding="utf-8", xml_declaration=True)

example("test", 'FRUITS')

内容的提问来源于stack exchange,提问作者Solomon Baker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 07:10:11