如何用Python读取含标签与文本混合的XML并精准还原文件
解决XML混合内容(标签+文本)的精准读取问题
问题场景
给定如下XML文件:
<?xml version="1.0" encoding="UTF-8"?> <document> <title> <tag>A</tag> X </title> </document>
需要精准还原原文件内容,既要保留<tag>标签结构,也要保留文本X。但默认的xml.etree.ElementTree处理标签与文本混合的<title>元素时存在缺陷:
itertext()会丢失标签结构,仅提取所有文本内容- 直接迭代元素只能获取子标签,无法捕获标签后的文本
X
测试代码及输出:
import xml.etree.ElementTree as ET tree = ET.parse("a.xml") r = tree.getroot() title = r[0] print(list(title.itertext())) print([c for c in title]) print(repr(title.text))
输出:
['\n ', 'A', '\n X\n '] [<Element 'tag' at 0x7fc11c130c20>] '\n '
解决思路
方法1:利用Element的tail属性手动遍历
xml.etree.ElementTree中,每个子元素的tail属性对应该标签结束后到下一个标签(或父元素结束)之间的文本。通过递归遍历元素的text、子元素、tail,可以完整还原内容结构:
import xml.etree.ElementTree as ET def serialize_element(el): parts = [] # 处理元素开头的文本 if el.text: parts.append(el.text) # 遍历子元素 for child in el: parts.append(f"<{child.tag}>") parts.extend(serialize_element(child)) parts.append(f"</{child.tag}>") # 处理子元素后的tail文本 if child.tail: parts.append(child.tail) return parts tree = ET.parse("a.xml") root = tree.getroot() # 序列化title元素 title_content = ''.join(serialize_element(root.find('title'))) print(title_content)
输出会完整保留<tag>A</tag>和后续的X,结合格式化可还原原文件排版。
方法2:使用lxml库(更简便)
lxml的tostring方法可直接保留原始混合内容结构,还支持格式化输出:
from lxml import etree tree = etree.parse("a.xml") title = tree.find('title') # 输出带格式的XML内容 print(etree.tostring(title, encoding='unicode', pretty_print=True))
输出:
<title> <tag>A</tag> X </title>
完全还原原文件的结构与排版。
内容的提问来源于stack exchange,提问作者Nico Schlömer
相关产品推荐
相关产品推荐

