Python怎么解析XML Python解析XML文件教程

9次阅读

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

Python怎么解析XML Python解析XML文件教程

Python解析XML最常用、最推荐的方式是用内置的xml.etree.ElementTree(简称ET),它轻量、标准、无需额外安装,适合大多数日常场景。如果需要处理特别复杂的XML(比如带命名空间、DTD验证、流式大文件),再考虑lxmlminidom

用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入门
    张三
  

  
    <a href="https://seo.sqjnqi.com/tag/%e6%95%b0%e6%8d%ae%e7%bb%93%e6%9e%84/"><b>数据结构</b></a>
    李四
  

解析代码:

立即学习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.textelem.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完全够用,不复杂但容易忽略细节。

text=ZqhQzanResources