使用lxml保存XML时特殊字符重复转义问题咨询
lxml保存XML时特殊字符重复转义问题解决
问题现象
使用lxml保存XML文件时,出现&被重复转义为&的问题:调试时确认字符串值正确,但写入文件后会多出额外的amp;;尝试先将XML转为字符串再保存,结果仍相同。
场景示例(字符串来自Excel,省略读取逻辑):
from lxml import etree import os root = etree.Element('root') child1 = etree.SubElement(root, 'stuff') child1.set('example', 'Example text & From excel file') et = etree.ElementTree(root) et.write(os.path.join(os.path.curdir, 'output.xml'), pretty_print=True)
预期输出属性值为Example text & From excel file,实际输出却为:
<root> <stuff example="Example text &amp;amp; From excel file"/> </root>
问题原因
XML规范要求特殊字符(如&、<、>等)必须转义,lxml在写入XML时会自动对属性或文本中的特殊字符进行转义处理。如果传入的字符串已经是转义后的内容(比如从Excel中读出的&),lxml会把字符串中的&再次转义为&,最终导致重复转义。
解决方法
方法1:传入未转义的原始字符串
如果Excel中的实际内容是未转义的(比如原本是&),直接将原始字符串传入属性,让lxml自动处理转义:
from lxml import etree import os root = etree.Element('root') child1 = etree.SubElement(root, 'stuff') # 传入原始字符串,lxml会自动将&转义为& child1.set('example', 'Example text & From excel file') et = etree.ElementTree(root) et.write(os.path.join(os.path.curdir, 'output.xml'), pretty_print=True)
此时文件中属性值会被正确转为Example text & From excel file,符合XML规范。
方法2:解码已转义字符串后再传入
如果只能获取到已转义的字符串,先用etree.unescape()将其还原为原始内容,再传入属性让lxml重新转义:
from lxml import etree import os # 从Excel读取的已转义字符串 escaped_str = 'Example text &amp; From excel file' # 解码为原始内容 original_str = etree.unescape(escaped_str) root = etree.Element('root') child1 = etree.SubElement(root, 'stuff') child1.set('example', original_str) et = etree.ElementTree(root) et.write(os.path.join(os.path.curdir, 'output.xml'), pretty_print=True)
解码后原始内容中的&会被还原为&,lxml写入时会再次转义为&,最终文件中得到预期的Example text &amp; From excel file。
内容的提问来源于stack exchange,提问作者user1904898
相关产品推荐
相关产品推荐

