Python解析XML最推荐使用内置的xml.etree.ElementTree(ET),轻量标准、无需安装,适合日常场景;复杂需求(如命名空间、大文件)再选lxml或minidom。

Python解析XML最常用、最推荐的方式是用内置的xml.etree.ElementTree(简称ET),它轻量、标准、无需额外安装,适合大多数日常场景。如果需要处理特别复杂的XML(比如带命名空间、DTD验证、流式大文件),再考虑lxml或minidom。
用ElementTree读取和遍历XML文件
ElementTree把XML转成树形结构,根元素是Element对象,支持XPath语法快速查找,代码简洁易懂。
- 用
ET.parse("file.xml")加载文件,返回ElementTree对象;调用.getroot()拿到根节点 - 用
.find("tag")找第一个匹配子元素,.findall("tag")找所有同级子元素,.iter("tag")深度遍历全文所有该标签 - 获取属性用
elem.get("attr_name"),获取文本内容用elem.text.strip()(注意空格和换行)
例如,有books.xml:
解析代码:
立即学习“Python免费学习笔记(深入)”;
import xml.etree.ElementTree as ET
tree = ET.parse("books.xml")
root = tree.getroot()
for book in root.findall("book"):
bid = book.get("id")
title = book.find("title").text.strip()
author = book.find("author").text.strip()
print(f"ID:{bid}, 书名:{title}, 作者:{author}")
用XPath精准定位复杂结构
ElementTree支持简化版XPath,比层层find更灵活。支持路径(如"book/author")、谓词(如"book[@id='1']")、通配符("*")等。
-
root.findall(".//author"):找所有author元素(不管嵌套几层) -
root.find("book[@id='2']/title"):找id为2的book下的title元素 -
root.findall("book[author='李四']"):找author子元素文本等于“李四”的book(注意:ElementTree不支持直接按文本筛选,需手动判断)
修改和写回XML文件
ElementTree不仅能读,还能改写。修改elem.text、elem.set("attr", "val")、elem.append(new_elem)、elem.remove(child)后,用tree.write("out.xml", encoding="utf-8", xml_declaration=True)保存。
- 新增元素:用
ET.SubElement(parent, "tag", attrib={...})创建并挂载 - 注意编码:写入时指定
encoding="utf-8"并加xml_declaration=True,避免中文乱码和缺少声明 - 默认不缩进,如需美观输出,可用
xml.dom.minidom辅助格式化(见下条)
处理中文乱码和格式美化(可选增强)
如果XML本身声明了encoding="gbk"但Python读取报错,用open()手动解码再解析:
with open("data.xml", "rb") as f:
content = f.read().decode("gbk")
root = ET.fromstring(content)
想让生成的XML带缩进和换行,可结合minidom:
from xml.dom import minidom
rough = ET.tostring(root, encoding="utf-8")
reparsed = minidom.parseString(rough)
pretty_xml = reparsed.toprettyxml(indent=" ", encoding="utf-8")
with open("pretty.xml", "wb") as f:
f.write(pretty_xml)
什么时候该用lxml?
当遇到以下情况时,建议装pip install lxml并替换导入:from lxml import etree:
- XML含复杂命名空间(
etree.XMLParser(resolve_entities=False)更健壮) - 需要CSS选择器支持(
root.cssselect("book > title")) - 处理几百MB以上的大文件(
iterparse支持边解析边清理内存) - 需要XSLT转换、DTD验证或XPath 2.0+高级函数
对90%的配置文件、接口返回、小数据交换,ElementTree完全够用,不复杂但容易忽略细节。










