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

将重音字符转为拉丁字符时避免ElementTree报错的方法

解决重音字符替换与ElementTree解析兼容问题

你遇到的核心问题是重音字符替换后破坏了XML的编码兼容性,再加上文件读取时的编码处理不当,才引发了一系列Unicode相关错误。我来一步步帮你搞定:

问题根源拆解

  1. 文件编码读取错误:你的代码里没给open()指定编码参数,Windows系统默认会用GBK编码读文件,如果你的XML实际是UTF-8编码,直接读就会乱码,后续解析自然报错。
  2. 重音替换方式太局限:手动用正则替换单个重音字符覆盖不全,很容易遗漏特殊情况,而且容易不小心破坏XML结构。
  3. 处理顺序不合理:转义&的操作和重音处理的顺序搞反了,容易导致不必要的重复转义,干扰XML解析。

修复后的完整代码

下面是调整后的代码,我会逐行解释关键改动:

# -- coding: utf-8 --
import xml.etree.ElementTree as ET
import os
import re
import unicodedata

path = r"C:\Users\SuperUser\Desktop\audit\audit\saved\audit"
root = ET.Element("root")

def remove_accents(text):
    # 用Unicode规范化把带重音的字符拆成「基础字符+重音标记」
    normalized_text = unicodedata.normalize('NFKD', text)
    # 过滤掉重音标记,只保留基础拉丁字符
    return ''.join(char for char in normalized_text if unicodedata.category(char) != 'Mn')

for filename in os.listdir(path):
    file_full_path = os.path.join(path, filename)
    # 1. 明确指定UTF-8编码读取文件,避免乱码
    with open(file_full_path, encoding='utf-8') as myfile:
        lines = myfile.readlines()
        for line in lines:
            # 2. 先统一去除所有重音字符
            line_without_accents = remove_accents(line)
            # 3. 再处理&的转义,保证XML语法合法
            line_escaped = re.sub(r"&(?!#\d{3};|amp;)", "&", line_without_accents)
            try:
                xmlVal = ET.fromstring(line_escaped)
                # 这里可以添加你需要的逻辑,比如把解析后的节点加入root
                root.append(xmlVal)
            except ET.ParseError as e:
                print(f"解析文件 {filename} 的行时出错: {e}")
                print(f"出错行片段: {line_escaped[:100]}...") # 打印部分内容方便排查

关键改动说明

  • 指定文件编码:open(file_full_path, encoding='utf-8')确保读取UTF-8编码的文件时不会乱码,如果你的文件是其他编码(比如GB2312),替换成对应编码即可。
  • 通用重音处理函数:remove_accents用Unicode规范化的方式处理重音,能覆盖所有带重音的拉丁字符(比如å→a、é→e、í→i、ü→u等),比手动写正则靠谱得多。
  • 调整处理顺序:先去重音再转义&,因为重音处理不会产生新的&,避免转义逻辑被干扰。
  • 异常捕获:添加try-except捕获解析错误,方便你快速定位哪一行出了问题,调试效率更高。

额外提醒

  • 如果你的Python版本是2.x,需要把字符串处理改成Unicode类型(比如line.decode('utf-8')),不过更建议升级到Python3,编码处理会直观很多。
  • 要确保你的XML每行都是完整的独立节点,如果是多行组成一个完整XML,readlines()逐行解析会出错,这种情况要读取整个文件内容再处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:00:59