本文目录导读:

- ElementTree(标准库)- 推荐使用
- lxml(第三方库)- 功能更强大
- minidom(标准库)- 基础但更直观
- cElementTree(标准库)- 高性能版本
- 实践示例:完整XML处理
- 性能对比和建议
- 选择建议
我来介绍几种在Python中解析XML数据的主要方法:
ElementTree(标准库)- 推荐使用
解析XML文件
import xml.etree.ElementTree as ET
# 解析XML字符串
xml_string = '''
<books>
<book id="1">
<title>Python编程</title>
<author>张三</author>
<price>59.9</price>
</book>
<book id="2">
<title>数据结构</title>
<author>李四</author>
<price>45.0</price>
</book>
</books>
'''
# 解析字符串
root = ET.fromstring(xml_string)
# 解析文件
# tree = ET.parse('books.xml')
# root = tree.getroot()
# 遍历所有book
for book in root.findall('book'):= book.find('title').text
author = book.find('author').text
price = book.find('price').text
book_id = book.get('id')
print(f"ID:{book_id}, 书名:{title}, 作者:{author}, 价格:{price}")
常用操作方法
# 获取根标签名
print(f"根标签: {root.tag}")
# 获取属性
for book in root.findall('book'):
print(f"Book ID: {book.get('id')}")
# 查找特定元素
python_book = root.find(".//book[title='Python编程']")
if python_book is not None:
print(f"找到: {python_book.find('title').text}")
# 直接访问子元素
for book in root:
print(book.find('title').text)
lxml(第三方库)- 功能更强大
from lxml import etree
# 解析XML
xml_string = '''
<books>
<book category="programming">
<title lang="en">Learning Python</title>
<author>Mark Lutz</author>
<year>2013</year>
</book>
<book category="data">
<title lang="en">Data Science</title>
<author>Jake VanderPlas</author>
<year>2016</year>
</book>
</books>
'''
root = etree.fromstring(xml_string)
# 支持XPath查询s = root.xpath('//title/text()')
print(f"所有书名: {titles}")
# 条件查询
programming_books = root.xpath("//book[@category='programming']/title/text()")
print(f"编程类书籍: {programming_books}")
# 创建新XML
new_book = etree.SubElement(root, "book")
new_book.set("category", "python")elem = etree.SubElement(new_book, "title")elem.text = "Python基础教程"
print(etree.tostring(root, pretty_print=True, encoding='unicode'))
minidom(标准库)- 基础但更直观
from xml.dom import minidom
# 解析XML
xml_string = '''
<students>
<student id="001">
<name>小明</name>
<age>20</age>
<grade>A</grade>
</student>
<student id="002">
<name>小红</name>
<age>21</age>
<grade>B</grade>
</student>
</students>
'''
dom = minidom.parseString(xml_string)
# 获取根元素
root = dom.documentElement
# 获取所有student元素
students = root.getElementsByTagName('student')
for student in students:
name = student.getElementsByTagName('name')[0].firstChild.data
age = student.getElementsByTagName('age')[0].firstChild.data
grade = student.getElementsByTagName('grade')[0].firstChild.data
student_id = student.getAttribute('id')
print(f"ID:{student_id}, 姓名:{name}, 年龄:{age}, 等级:{grade}")
cElementTree(标准库)- 高性能版本
# Python 3.3+直接使用ElementTree,它会自动使用C实现
import xml.etree.ElementTree as ET
# 如果需要明确使用C实现(Python 3.3以下版本)
try:
import xml.etree.cElementTree as ET
except ImportError:
import xml.etree.ElementTree as ET
# 后续使用相同
实践示例:完整XML处理
import xml.etree.ElementTree as ET
import json
class XMLProcessor:
def __init__(self, xml_string=None, file_path=None):
if xml_string:
self.root = ET.fromstring(xml_string)
elif file_path:
tree = ET.parse(file_path)
self.root = tree.getroot()
else:
self.root = None
def to_dict(self, element=None):
"""将XML转换为字典"""
if element is None:
element = self.root
result = {}
# 处理属性
if element.attrib:
result['@attributes'] = element.attrib
# 处理子元素
children = list(element)
if children:
child_dict = {}
for child in children:
child_data = self.to_dict(child)
tag = child.tag
# 处理重复标签
if tag in child_dict:
if not isinstance(child_dict[tag], list):
child_dict[tag] = [child_dict[tag]]
child_dict[tag].append(child_data)
else:
child_dict[tag] = child_data
result.update(child_dict)
# 处理文本内容
text = element.text and element.text.strip()
if text and not result:
result = text
elif text:
result['#text'] = text
return result
def find_all(self, tag_name):
"""查找所有指定标签的元素"""
return self.root.findall(f'.//{tag_name}')
def find_by_attribute(self, tag_name, attr_name, attr_value):
"""根据属性查找元素"""
xpath = f".//{tag_name}[@{attr_name}='{attr_value}']"
return self.root.find(xpath)
# 使用示例
xml_data = '''
<config>
<database>
<host>localhost</host>
<port>3306</port>
<name>testdb</name>
</database>
<app>
<name>MyApp</name>
<version>1.0.0</version>
<settings>
<setting key="debug">true</setting>
<setting key="max_users">100</setting>
</settings>
</app>
</config>
'''
processor = XMLProcessor(xml_string=xml_data)
# 转换为字典
config_dict = processor.to_dict()
print(json.dumps(config_dict, indent=2, ensure_ascii=False))
# 查找特定元素
host_elem = processor.find_all('host')
print(f"数据库主机: {host_elem[0].text if host_elem else '未找到'}")
debug_setting = processor.find_by_attribute('setting', 'key', 'debug')
if debug_setting is not None:
print(f"Debug模式: {debug_setting.text}")
性能对比和建议
# 性能基准测试
import time
import xml.etree.ElementTree as ET
from lxml import etree
# 生成测试数据
test_xml = '<root>' + ''.join([f'<item id="{i}"><name>Item{i}</name></item>' for i in range(10000)]) + '</root>'
# ElementTree
start = time.time()
root = ET.fromstring(test_xml)
items = root.findall('item')
et_time = time.time() - start
# lxml
start = time.time()
root = etree.fromstring(test_xml)
items = root.xpath('//item')
lxml_time = time.time() - start
print(f"ElementTree: {et_time:.4f}s")
print(f"lxml: {lxml_time:.4f}s")
选择建议
| 方法 | 适用场景 | 性能 | 功能 |
|---|---|---|---|
| ElementTree | 通用场景,标准库 | 中等 | 基础功能 |
| lxml | 复杂查询,大数据 | 高 | 最强大 |
| minidom | 简单操作,兼容性 | 低 | 基础功能 |
| cElementTree | Python 2.x | 高 | 同ElementTree |
推荐:日常使用 ElementTree(标准库,无需安装),复杂场景使用 lxml。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播