使用Python的xml.etree.ElementTree写入文件时如何保留HTML标签?
问题解答
1. 需求实现方案
你遇到的转义问题是xml.etree.ElementTree的标准合规行为:XML规范要求文本节点中不能直接包含<、>等标签起始符号,因此赋值到.text属性的内容会被自动转义为<、>。你可以通过两种方案实现需求:
方案1:合法XML结构实现(推荐用于需求合理的场景)
如果<title>节点允许包含br、sup等子元素,直接将待插入内容解析为XML元素节点再插入,即可保留标签格式:
import xml.etree.ElementTree as ET tree = ET.parse('example.xml') root = tree.getroot() # 注意修正原字符串中的错误实体写法,&$174为非法XML实体,正确写法为® to_sub_content = "<temp>This is a test of <br/> Hershey's <sup>®</sup> chocolate factory machine</temp>" temp_node = ET.fromstring(to_sub_content) title_node = root.find('title') # 清空原有内容 title_node.clear() # 复制临时节点的内容到title节点 title_node.text = temp_node.text for child in temp_node: title_node.append(child) # 若需要强制保留®不转换为实际®符号,可在序列化后做字符串替换 output = ET.tostring(root, encoding='UTF-8', xml_declaration=True).decode('UTF-8') output = output.replace('®', '®') with open('example_mod.xml', 'w', encoding='UTF-8') as f: f.write(output)
该方案输出的是完全符合XML规范的文档,可被所有标准XML解析器正常识别。
方案2:强制替换转义字符(不推荐)
如果你必须输出不符合XML规范的文本嵌套标签格式,可以序列化后全局替换转义字符:
import xml.etree.ElementTree as ET tree = ET.parse('example.xml') root = tree.getroot() to_sub_text = "This is a test of <br/> Hershey's <sup>®</sup> chocolate factory machine" spot = root.find('title') spot.text = to_sub_text # 序列化后替换转义字符 output = ET.tostring(root, encoding='UTF-8', xml_declaration=True).decode('UTF-8') output = output.replace('<', '<').replace('>', '>').replace('&', '&') with open('example_mod.xml', 'w', encoding='UTF-8') as f: f.write(output)
该方案风险极高,若文本内容中本身包含需要转义的<、>符号,会导致整个XML文档结构损坏,无法被正常解析。
2. 最佳实践说明
你要求的输出格式不符合XML行业最佳实践,本质属于非法XML文档:
- XML规范明确要求文本节点内的标签起始符号必须转义,否则标准XML解析器会将
<br/>识别为子元素,若XML Schema未定义<title>下可包含此类子元素,文档会被判定为无效。 - 强制输出未转义的标签会导致后续所有依赖标准XML工具的处理流程出错,维护成本极高。
更合理的处理方式是优先和需求团队沟通,选择两种合规方案之一:
- 调整XML结构定义,允许
<title>节点下包含br、sup等格式化子元素,对应上述方案1的实现。 - 保持当前的转义输出,要求使用方读取内容后自行反转义处理HTML标签和实体。
内容的提问来源于stack exchange,提问作者gammapoint
相关产品推荐
相关产品推荐

