4.12 Python3 XML 解析

Python 提供了多种处理 XML 的方式,三种方法解析 XML:ElementTree、SAX 以及 DOM。

1. ElementTree

xml.etree.ElementTree 是 Python 标准库中用于处理 XML 的模块,它提供了简单而高效的 API,用于解析和生成 XML 文档。

2.SAX (simple API for XML )

Python 标准库包含 SAX 解析器,SAX 用事件驱动模型,通过在解析 XML 的过程中触发一个个的事件并调用用户定义的回调函数来处理 XML 文件。

3.DOM(Document Object Model)

将 XML 数据在内存中解析成一个树,通过对树的操作来操作 XML。


目录

1. xml.etree.ElementTree (推荐)

1.1 基本用法

1.2 遍历 XML 树

1.3 访问元素数据

1.4 修改 XML

1.5 命名空间处理

2. xml.dom.minidom

2.1 基本用法

2.2 访问数据

3. xml.sax

3.1 基本用法

4. lxml (第三方库)

4.1 安装

4.2 基本用法

5. XML 解析方法对比

6. 实际应用示例

6.1 解析 RSS 订阅

6.2 生成 XML 文件

6.3 转换 XML 为字典

7. 安全注意事项


1. xml.etree.ElementTree (推荐)

ElementTree 是 Python 标准库中最常用的 XML 处理模块,它提供了轻量级且高效的 API。

1.1 基本用法

import xml.etree.ElementTree as ET

# 解析 XML 文件
tree = ET.parse('example.xml')
root = tree.getroot()

# 或者直接解析字符串
xml_string = '<root><child>Content</child></root>'
root = ET.fromstring(xml_string)

1.2 遍历 XML 树

# 遍历所有子节点
for child in root:
    print(child.tag, child.attrib)

# 递归遍历所有元素
for elem in root.iter():
    print(elem.tag, elem.text)

# 查找特定标签
for neighbor in root.iter('neighbor'):
    print(neighbor.attrib)

1.3 访问元素数据

# 访问元素属性
print(root[0].attrib['name'])

# 访问元素文本内容
print(root[0].text)

# 使用 find 方法
country = root.find("country")
rank = country.find('rank').text

1.4 修改 XML

# 修改元素文本
root[0][0].text = "New Rank"

# 修改元素属性
root[0].attrib['name'] = 'Updated Name'

# 添加新元素
new_elem = ET.SubElement(root, 'newchild')
new_elem.text = "New Content"

# 删除元素
root.remove(root[0])

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

1.5 命名空间处理

# 注册命名空间
ET.register_namespace('', "http://example.com/ns")

# 带命名空间的查找
namespaces = {'ns': 'http://example.com/ns'}
for elem in root.findall('ns:child', namespaces):
    print(elem.text)

2. xml.dom.minidom

minidom 提供了 DOM (Document Object Model) 方式的 XML 解析,适合需要完整 DOM 功能的场景。

2.1 基本用法

from xml.dom import minidom

# 解析 XML
doc = minidom.parse('example.xml')

# 获取根元素
root = doc.documentElement

# 获取元素列表
items = root.getElementsByTagName('item')

2.2 访问数据

# 获取第一个 item
first_item = items[0]

# 获取属性
print(first_item.getAttribute('id'))

# 获取文本内容
print(first_item.firstChild.data)

3. xml.sax

SAX (Simple API for XML) 是基于事件驱动的解析方式,适合处理大型 XML 文件。

3.1 基本用法

import xml.sax

class MyHandler(xml.sax.ContentHandler):
    def startElement(self, name, attrs):
        print(f"开始元素: {name}")
        
    def endElement(self, name):
        print(f"结束元素: {name}")
        
    def characters(self, content):
        print(f"内容: {content.strip()}")

# 创建解析器
parser = xml.sax.make_parser()
parser.setContentHandler(MyHandler())

# 解析 XML
parser.parse('example.xml')

4. lxml (第三方库)

lxml 是一个功能强大的第三方库,兼容 ElementTree API 但提供了更多功能。

4.1 安装

pip install lxml

4.2 基本用法

from lxml import etree

# 解析 XML
tree = etree.parse('example.xml')
root = tree.getroot()

# XPath 查询
results = root.xpath('//country[@name="Singapore"]')
for r in results:
    print(etree.tostring(r))

5. XML 解析方法对比

方法/特性ElementTreeminidomSAXlxml
内存使用中等中等
速度最快非常快
API 易用性简单复杂复杂简单
支持 XPath有限完全支持
适合文件大小中小型小型大型各种大小

6. 实际应用示例

6.1 解析 RSS 订阅

import xml.etree.ElementTree as ET
import urllib.request

# 下载并解析 RSS
url = 'https://example.com/feed.rss'
with urllib.request.urlopen(url) as response:
    tree = ET.parse(response)

root = tree.getroot()

# 提取新闻条目
for item in root.findall('.//item'):
    title = item.find('title').text
    link = item.find('link').text
    print(f"{title}\n{link}\n")

6.2 生成 XML 文件

python

复制

下载

import xml.etree.ElementTree as ET

# 创建根元素
root = ET.Element('catalog')

# 添加子元素
for i in range(1, 4):
    book = ET.SubElement(root, 'book', id=str(i))
    title = ET.SubElement(book, 'title')
    title.text = f"Book {i}"
    author = ET.SubElement(book, 'author')
    author.text = f"Author {i}"

# 创建 ElementTree 对象并保存
tree = ET.ElementTree(root)
tree.write('books.xml', encoding='utf-8', xml_declaration=True)

6.3 转换 XML 为字典

def xml_to_dict(element):
    result = {}
    for child in element:
        if len(child) == 0:
            result[child.tag] = child.text
        else:
            result[child.tag] = xml_to_dict(child)
    return result

root = ET.parse('data.xml').getroot()
data_dict = xml_to_dict(root)
print(data_dict)

7. 安全注意事项

  1. XML 炸弹:防范类似 "billion laughs" 的攻击

    parser = ET.XMLParser(resolve_entities=False)  # 禁用实体解析
  2. 敏感数据:XML 可能包含敏感信息,解析时注意保护

  3. 输入验证:始终验证输入的 XML 数据


对于大多数应用场景,xml.etree.ElementTree 是最佳选择,它平衡了性能和易用性。对于需要高性能或高级功能(如完整 XPath 支持)的场景,可以考虑使用 lxml

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值