Python自动化实战:ElementTree库快速入门指南

一、ElementTree 库简介

xml.etree.ElementTree 是 Python 处理 XML 的标准库,它:

  • 轻量高效:比 DOM 解析器更简单,比 SAX 解析器更易用
  • 内置模块:无需安装任何第三方包
  • Pythonic API:使用方式符合 Python 习惯

二、核心操作快速上手

1. 解析 XML:读取与理解

python 复制代码
import xml.etree.ElementTree as ET

# 从字符串解析
xml_string = '''
<bookstore>
    <book category="编程">
        <title>Python编程从入门到实践</title>
        <author>Eric Matthes</author>
        <year>2016</year>
        <price>89.00</price>
    </book>
</bookstore>
'''
root = ET.fromstring(xml_string)  # 获取根元素

# 从文件解析
tree = ET.parse('books.xml')      # 解析文件
root = tree.getroot()             # 获取根元素

print(f"根元素标签: {root.tag}")   # 输出: bookstore

2. 遍历与访问元素

python 复制代码
# 遍历所有子元素
for child in root:
    print(f"子元素: {child.tag}, 属性: {child.attrib}")
    # 访问孙子元素
    for subchild in child:
        print(f"  {subchild.tag}: {subchild.text}")

# 访问特定元素的文本
title = root.find('book/title')  # 查找第一个匹配的元素
if title is not None:
    print(f"书名: {title.text}")

# 查找所有符合条件的元素
all_books = root.findall('book')  # 查找所有book元素
print(f"找到 {len(all_books)} 本书")

3. 创建 XML 文档

python 复制代码
# 创建根元素
root = ET.Element("bookstore")

# 创建子元素并添加属性
book = ET.SubElement(root, "book")
book.set("category", "编程")

# 添加更多子元素
title = ET.SubElement(book, "title")
title.text = "Python核心编程"
author = ET.SubElement(book, "author")
author.text = "Wesley Chun"

# 创建XML树并写入文件
tree = ET.ElementTree(root)
tree.write("new_book.xml", encoding="utf-8", xml_declaration=True)

print("XML文件创建成功!")

4. 修改 XML 内容

python 复制代码
# 修改元素文本
for price in root.iter('price'):  # iter()遍历所有price元素
    old_price = float(price.text)
    price.text = str(old_price * 0.9)  # 打9折
    price.set('discount', '10%')       # 添加新属性

# 删除元素
for book in root.findall('book'):
    year = book.find('year')
    if year is not None and int(year.text) < 2010:
        root.remove(book)  # 删除2010年以前的书

# 保存修改
tree.write('updated_books.xml')

5. 查找元素的多种方式

python 复制代码
# 1. 使用XPath-like语法(有限支持)
expensive_books = root.findall("book[price>50]")  # 价格>50的书

# 2. 遍历所有特定标签
for author in root.iter('author'):
    print(f"作者: {author.text}")

# 3. 复杂条件查找
for book in root.findall('book'):
    price = float(book.find('price').text)
    category = book.get('category')
    if price > 80 and category == '编程':
        print(f"昂贵的编程书: {book.find('title').text}")

三、实用技巧与注意事项

处理命名空间

python 复制代码
# 带命名空间的XML
ns_xml = '''
<root xmlns:bk="http://example.com/books">
    <bk:book>
        <bk:title>Python学习手册</bk:title>
    </bk:book>
</root>
'''

# 注册命名空间前缀(方便查找)
namespaces = {'bk': 'http://example.com/books'}
root = ET.fromstring(ns_xml)
title = root.find('bk:book/bk:title', namespaces)

处理大型 XML 文件

python 复制代码
# 使用迭代解析,节省内存
for event, elem in ET.iterparse('large_file.xml', events=('start', 'end')):
    if event == 'start' and elem.tag == 'book':
        print(f"开始处理书: {elem.find('title').text}")
    elif event == 'end' and elem.tag == 'book':
        # 处理完成后清除元素,释放内存
        elem.clear()

# 只解析特定元素
context = ET.iterparse('large_file.xml', events=('end',))
for event, elem in context:
    if elem.tag == 'book' and event == 'end':
        # 只处理book元素
        process_book(elem)
        elem.clear()

四、常见错误与解决方法

错误情况 原因 解决方法
SyntaxError XML格式不正确 检查XML是否完整,标签是否闭合
AttributeError 元素不存在就访问属性 先用if elem is not None:判断
中文乱码 编码问题 确保读写时指定encoding='utf-8'
找不到元素 命名空间问题 注册并使用命名空间前缀

五、快速参考表

任务 方法 示例
解析XML ET.parse() tree = ET.parse('file.xml')
获取根 .getroot() root = tree.getroot()
查找单个 .find() elem = root.find('path')
查找所有 .findall() elems = root.findall('path')
遍历所有 .iter() for el in root.iter('tag'):
获取文本 .text text = elem.text
获取属性 .attrib attr = elem.attrib
设置属性 .set() elem.set('key', 'value')
创建元素 ET.SubElement() child = ET.SubElement(parent, 'tag')
相关推荐
stark张宇5 小时前
Go语言核心三剑客:数组、切片与结构体使用指南
后端·go
洛小豆6 小时前
她问我:数据库还在存 Timestamp?我说:大人,时代变了
数据库·后端·mysql
Aevget6 小时前
智能高效Go开发工具GoLand v2025.3全新上线——新增资源泄漏分析
开发语言·ide·后端·golang·go
廖广杰6 小时前
线程池深度解析
后端
邵伯6 小时前
为什么你的 SELECT 有时会阻塞?
数据库·后端
Sailing6 小时前
AI 流式对话该怎么做?SSE、fetch、axios 一次讲清楚
前端·javascript·面试
洛小豆6 小时前
代码修仙录 · 第1期:宗门大阵崩了?只因少了毫秒三魂!
数据库·后端·mysql
她说..6 小时前
Spring 核心工具类 AopUtils 超详细全解
java·后端·spring·springboot·spring aop
无限大66 小时前
为什么"缓存"能提高系统性能?——从 CPU 缓存到分布式缓存
后端·面试