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

Python LXML:如何在resources标签下添加元素并规范格式

Android资源XML添加元素后的格式修复方案

使用Python的xml.etree.ElementTree操作Android资源XML时,添加<string>元素后出现格式问题:新元素无正确缩进,且与</resources>标签挤在一起。以下是问题代码、效果对比及纯Python解决方案:

问题代码

import xml.etree.ElementTree as Et

parser = Et.XMLParser(strip_cdata=False)
xml_tree = Et.parse(destination_xml_file_full_path, parser=parser)
xml_tree_root_element = xml_tree.getroot()

string_element = Et.Element('string')
string_element.set('name', string_id)
string_element.text = ''

xml_tree_root_element.append(string_element)

xml_tree.write(destination_xml_file_full_path, encoding='UTF-8', xml_declaration=False, pretty_print=True)

预期格式

<resources>
    <string name="cbp_payment_successful">Payment Successful</string>
    ...
    <string name="string id"></string>

</resources>

实际错误格式

<resources>
    <string name="cbp_payment_successful">Payment Successful</string>
    ...

<string name="string id"></string></resources>

解决方案1:手动控制元素的缩进与换行

ElementTree的pretty_print对空文本元素的格式处理存在缺陷,可通过设置元素的tail属性来修正格式:

import xml.etree.ElementTree as Et

parser = Et.XMLParser(strip_cdata=False)
xml_tree = Et.parse(destination_xml_file_full_path, parser=parser)
root = xml_tree.getroot()

new_string = Et.Element('string')
new_string.set('name', string_id)
new_string.text = ''

# 定义缩进格式(匹配现有XML的4空格缩进)
indent = '    '
# 设置新元素的尾文本,确保</resources>前有换行
new_string.tail = '\n'

# 调整最后一个子元素的尾文本,保证新元素有正确缩进
if root:
    last_child = root[-1]
    # 确保最后一个原有元素的尾文本是换行+缩进
    if not (last_child.tail and last_child.tail.endswith(f'\n{indent}')):
        last_child.tail = f'\n{indent}'

root.append(new_string)
xml_tree.write(destination_xml_file_full_path, encoding='UTF-8', xml_declaration=False, pretty_print=True)

解决方案2:插入到最后一个元素之后

找到<resources>下的最后一个<string>元素,用insert方法插入新元素,同步调整缩进:

import xml.etree.ElementTree as Et

parser = Et.XMLParser(strip_cdata=False)
xml_tree = Et.parse(destination_xml_file_full_path, parser=parser)
root = xml_tree.getroot()

new_string = Et.Element('string')
new_string.set('name', string_id)
new_string.text = ''
indent = '    '
new_string.tail = '\n'

# 查找所有<string>元素
string_elements = root.findall('string')
if string_elements:
    last_string_pos = root.index(string_elements[-1])
    # 插入到最后一个<string>的下一位
    root.insert(last_string_pos + 1, new_string)
    # 给最后一个原有<string>设置正确的尾文本
    string_elements[-1].tail = f'\n{indent}'
else:
    # 若没有<string>元素,直接追加并设置格式
    root.append(new_string)

xml_tree.write(destination_xml_file_full_path, encoding='UTF-8', xml_declaration=False, pretty_print=True)

方案3:借助xml.dom.minidom实现完美格式化

如果对格式要求较高,可结合xml.dom.minidom进行二次格式化,规避ElementTree的pretty_print局限:

import xml.etree.ElementTree as Et
import xml.dom.minidom as minidom

parser = Et.XMLParser(strip_cdata=False)
xml_tree = Et.parse(destination_xml_file_full_path, parser=parser)
root = xml_tree.getroot()

new_string = Et.Element('string')
new_string.set('name', string_id)
new_string.text = ''
root.append(new_string)

# 转换为minidom对象并格式化
rough_xml = Et.tostring(root, 'utf-8')
dom = minidom.parseString(rough_xml)
formatted_xml = dom.toprettyxml(indent='    ', encoding='UTF-8').decode('utf-8')

# 移除多余空行(可选)
formatted_xml = '\n'.join(line for line in formatted_xml.split('\n') if line.strip()) + '\n'

# 写入文件
with open(destination_xml_file_full_path, 'w', encoding='UTF-8') as f:
    f.write(formatted_xml)

内容的提问来源于stack exchange,提问作者Francis Bacon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 15:45:43