Python XML 解析(长文解析)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
  • 《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

前言

在现代软件开发中,XML(可扩展标记语言)因其结构清晰、跨平台兼容性强的特点,被广泛应用于数据交换、配置文件存储、服务接口定义等领域。对于 Python 开发者而言,掌握 XML 解析技术不仅能提升数据处理效率,还能增强系统与外部系统的交互能力。本文将从零开始,结合实际案例和代码示例,系统讲解 Python 中 XML 解析的核心方法,并提供进阶技巧,帮助读者快速上手这一技能。


XML 的基础概念与结构

什么是 XML?

XML(eXtensible Markup Language)是一种用于标记电子文件格式的标记语言。它通过自定义标签描述数据结构,允许开发者自由定义数据类型和层级关系。例如,一个天气数据的 XML 可能如下:

<weather>
    <city>Beijing</city>
    <temperature>25°C</temperature>
    <condition>cloudy</condition>
</weather>

这里,<weather> 是根节点,<city><temperature> 等是子节点,内容则存储具体数据。

XML 的树形结构比喻

XML 文档可以类比为一棵“数据树”:

  • 根节点:树干,代表整个文档的起点。
  • 子节点/元素:树枝,通过嵌套形成层级关系。
  • 属性:叶子上的装饰,用 @符号 表示额外信息(如 <person age="30">)。
  • 文本内容:叶子上的果实,存储实际数据。

理解这一结构是解析 XML 的关键。


Python 中的 XML 解析库

Python 提供了多种解析 XML 的库,最常用的包括:

  1. xml.etree.ElementTree(内置库,简称 ET)
  2. lxml(高性能第三方库,功能更强大)
  3. xml.dom.minidom(DOM 解析,适合小规模文档)

以下是各库的对比表格:

库名特点适用场景
xml.etree.ElementTree内置、轻量、API 简洁日常解析、中小型 XML 文件
lxml支持 XPath 和 XSLT,速度更快复杂查询、大规模数据处理
xml.dom.minidom基于 DOM 模型,操作直观但内存占用高需要修改 XML 结构的简单场景

使用 ElementTree 进行基础解析

安装与导入

xml.etree.ElementTree 是 Python 标准库,无需额外安装:

import xml.etree.ElementTree as ET  

解析 XML 文件

假设有一个 data.xml 文件:

<library>  
    <book id="101">  
        <title>Python Crash Course</title>  
        <author>Eric Matthes</author>  
        <price>35.99</price>  
    </book>  
    <book id="102">  
        <title>Learning XML</title>  
        <author>Erik T. Ray</author>  
        <price>42.50</price>  
    </book>  
</library>  

步骤 1:加载 XML

tree = ET.parse("data.xml")  
root = tree.getroot()  # 获取根节点 <library>  

步骤 2:遍历节点

通过 iter()findall() 方法查找子节点:

for book in root.iter("book"):  
    title = book.find("title").text  
    price = book.find("price").text  
    print(f"Book: {title}, Price: {price}")  

步骤 3:处理属性

获取节点的属性值:

book_id = book.get("id")  # 获取属性 @id  

创建 XML 文件

ElementTree 也支持从头构建 XML:

root = ET.Element("library")  

new_book = ET.SubElement(root, "book", {"id": "103"})  
ET.SubElement(new_book, "title").text = "Mastering XML"  
ET.SubElement(new_book, "price").text = "29.99"  

tree = ET.ElementTree(root)  
tree.write("new_data.xml", encoding="utf-8", xml_declaration=True)  

使用 lxml 解析 XML(进阶功能)

安装与导入

需安装 lxml 库:

pip install lxml  

然后导入:

from lxml import etree  

XPath 查询的强大功能

XPath 是一种在 XML 文档中定位节点的语言,类似于 SQL 对数据库的查询。例如:

tree = etree.parse("data.xml")  
root = tree.getroot()  

for book in root.xpath("//book[price>30]"):  
    print(etree.tostring(book, pretty_print=True).decode())  

命名空间处理

当 XML 包含命名空间时(如 <ns:book>),需先定义命名空间前缀:

ns = {"ns": "http://example.com"}  
for book in root.xpath("//ns:book", namespaces=ns):  
    print(book.find("ns:title", namespaces=ns).text)  

实战案例:解析天气 API 响应

场景描述

假设我们从第三方 API 获取了以下 XML 格式的天气数据:

<weather_data>  
    <location>  
        <city>Shanghai</city>  
        <country>China</country>  
    </location>  
    <forecast>  
        <day>2023-10-01</day>  
        <condition>sunny</condition>  
        <temp>28°C</temp>  
    </forecast>  
    <forecast>  
        <day>2023-10-02</day>  
        <condition>rainy</condition>  
        <temp>22°C</temp>  
    </forecast>  
</weather_data>  

解析与数据提取

import xml.etree.ElementTree as ET  

def parse_weather(xml_file):  
    tree = ET.parse(xml_file)  
    root = tree.getroot()  

    # 获取城市信息  
    city = root.find("location/city").text  
    country = root.find("location/country").text  
    print(f"Weather for {city}, {country}:")  

    # 遍历所有 forecast 节点  
    for forecast in root.findall("forecast"):  
        day = forecast.find("day").text  
        condition = forecast.find("condition").text  
        temp = forecast.find("temp").text  
        print(f"  {day}: {condition}, {temp}")  

parse_weather("weather.xml")  

输出结果:

Weather for Shanghai, China:  
  2023-10-01: sunny, 28°C  
  2023-10-02: rainy, 22°C  

常见问题与解决方案

问题 1:XML 格式错误导致解析失败

解决方案:使用 xml.dom.minidom 验证 XML 合法性:

from xml.dom.minidom import parse  
try:  
    dom = parse("invalid.xml")  
except Exception as e:  
    print(f"XML 格式错误: {str(e)}")  

问题 2:处理大文件时内存不足

解决方案:使用 迭代解析(Iterparse):

import xml.etree.ElementTree as ET  

for event, elem in ET.iterparse("large_file.xml", events=("start", "end")):  
    if elem.tag == "book" and event == "end":  
        # 处理当前 <book> 节点后立即释放内存  
        print(elem.find("title").text)  
        elem.clear()  

问题 3:特殊字符未转义

解决方案:使用 xml.sax.saxutils 进行转义:

from xml.sax.saxutils import escape, unescape  

raw_text = "<title>XML & Basics</title>"  
escaped_text = escape(raw_text)  # 转义为 "&lt;title&gt;XML &amp; Basics&lt;/title&gt;"  

总结

Python XML 解析技术为开发者提供了灵活的数据处理能力,无论是读取配置文件、解析 API 响应,还是生成结构化数据,都能找到合适的工具和方法。通过本文的案例和代码示例,读者可以快速掌握基础语法,并逐步探索更复杂的场景,如 XPath 查询或命名空间处理。

对于初学者,建议从 xml.etree.ElementTree 入手,熟悉节点遍历和属性操作;中级开发者则可深入学习 lxml 的高级功能,如 XPath 和 XSLT 转换。随着实践的深入,XML 解析将成为你工具箱中不可或缺的一部分,助力复杂项目的高效开发。


通过本文的学习,希望读者能对 Python XML 解析有全面的理解,并在实际项目中灵活运用这些技术。如需进一步探讨或有具体场景的疑问,欢迎在评论区交流!

最新发布