On this page

Python XML 解析

Python XML 解析指南

Python提供了多种解析XML文档的方法,主要包括以下几种方式:

1. xml.etree.ElementTree (推荐)

这是Python标准库中最简单高效的XML解析方式。

import xml.etree.ElementTree as ET

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

# 解析XML字符串
# xml_string = '<root><child>content</child></root>'
# root = ET.fromstring(xml_string)

# 遍历元素
for child in root:
    print(child.tag, child.attrib)

# 访问特定元素
for elem in root.iter('item'):
    print(elem.text)

# 查找元素
for elem in root.findall('.//nelement[@attr="value"]'):
    print(elem.text)

# 修改XML
for price in root.iter('price'):
    new_price = float(price.text) * 1.1
    price.text = str(new_price)
    price.set('updated', 'yes')

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

2. xml.dom.minidom

DOM方式会将整个XML文档加载到内存,适合处理较小的XML文件。

from xml.dom import minidom

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

# 获取元素
root = doc.documentElement
items = root.getElementsByTagName('item')

# 访问数据
for item in items:
    print(item.firstChild.data)

# 创建新XML
doc = minidom.Document()
root = doc.createElement('root')
doc.appendChild(root)

item = doc.createElement('item')
item.appendChild(doc.createTextNode('content'))
root.appendChild(item)

# 保存XML
with open('new.xml', 'w') as f:
    doc.writexml(f, indent='', addindent=' ', newl='\n')

3. xml.sax

SAX是基于事件的解析器,适合处理大型XML文件(流式处理)。

import xml.sax

class MyHandler(xml.sax.ContentHandler):
    def __init__(self):
        self.current = ""
        self.content = ""
    
    def startElement(self, tag, attributes):
        self.current = tag
        if tag == "item":
            print("----- ITEM -----")
            print("ID:", attributes["id"])
    
    def characters(self, content):
        if self.current == "name":
            self.content = content
    
    def endElement(self, tag):
        if tag == "name":
            print("Name:", self.content)
        self.current = ""

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

4. 第三方库 lxml

lxml功能更强大,支持XPath和XSLT。

from lxml import etree

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

# XPath查找
items = root.xpath('//item[price>10]')

# 修改元素
for item in items:
    item.find('price').text = '9.99'

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

选择建议

  • 对于简单需求,使用标准库的xml.etree.ElementTree
  • 需要处理大型XML文件时,考虑xml.sax
  • 需要完整DOM支持时,使用xml.dom.minidom
  • 需要高级功能(XPath/XSLT)时,使用lxml

注意事项

  • XML解析可能面临安全风险,如XML炸弹、XXE攻击等,处理不可信XML时要小心
  • 考虑使用defusedxml包来安全地解析XML