Python中XML解析、属性修改及写入时如何保持UTF-8编码?
问题原因与解决方案
问题根源
你遇到的实体编码问题,是因为xml.etree.ElementTree的ET.tostring()方法默认会将非ASCII字符(比如ó、é)转换为XML实体引用(如ó、é)。虽然这符合XML规范,但不符合你保留原始UTF-8字符的需求。
解决方案
修改ET.tostring()的调用参数,让它直接输出不转义的Unicode字符串,同时优化代码效率:
修改后的代码
import xml.etree.ElementTree as ET from googletrans import Translator # 仅初始化一次翻译器,避免循环内重复创建 translator = Translator() with open("input file.txt", "r", encoding='utf-8') as input_file: with open("output file.txt", "w", encoding='utf-8') as output_file: for ligne in input_file: # 处理空行,保留原格式 stripped_line = ligne.strip() if not stripped_line: output_file.write(ligne) continue # 尝试解析XML元素,非元素行直接原样写入 try: root = ET.fromstring(stripped_line) except ET.ParseError: output_file.write(ligne) continue # 仅当元素存在CH属性时进行翻译 current_text = root.get("CH") if current_text: translated_text = translator.translate(dest="pt", src="fr", text=current_text) root.attrib["CH"] = translated_text.text # 生成不转义特殊字符的XML字符串 decoded_string = ET.tostring(root, encoding='unicode') # 保持原行的缩进格式,直接写入并换行 output_file.write(decoded_string + '\n')
关键修改点
ET.tostring(root, encoding='unicode')
指定encoding='unicode'后,方法会直接返回Unicode字符串,不会对UTF-8范围内的特殊字符进行实体转义,这样就能保留vitória、é这类原始字符。翻译器初始化移到循环外
原代码每次循环都创建Translator实例,会造成不必要的性能开销,移到循环外仅初始化一次即可。增加异常处理
针对XML声明、空行这类非元素行,直接原样写入,避免解析报错。
验证结果
修改后,输出文件的CH属性值会保留原始UTF-8字符,符合你的预期:
<?xml version="1.0" encoding="UTF-8"?> <SCRIBUSUTF8NEW Version="1.5.5"> <StoryText> <DefaultStyle ALIGN="1" SCALEV="100" BASEO="0" KERN="0"/> <ITEXT FONT="Times New Roman Bold" BASEO="0" KERN="0" CH="A vitória é nossa" /> <para ALIGN="1" LINESP="10"/> <ITEXT FONT="Times New Roman Bold" SCALEH="100" SCALEV="100" BASEO="0" KERN="0" CH="Vida longa ao" /> <trail ALIGN="1" LINESP="10"/> </StoryText> </SCRIBUSUTF8NEW>
内容的提问来源于stack exchange,提问作者JB B
相关产品推荐
相关产品推荐

