Python脚本如何解析XML数据

wen 实用脚本 1

本文目录导读:

Python脚本如何解析XML数据

  1. ElementTree(标准库)- 推荐使用
  2. lxml(第三方库)- 功能更强大
  3. minidom(标准库)- 基础但更直观
  4. cElementTree(标准库)- 高性能版本
  5. 实践示例:完整XML处理
  6. 性能对比和建议
  7. 选择建议

我来介绍几种在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

抱歉,评论功能暂时关闭!