在Python中操作XML主要可以通过标准库的xml.etree.ElementTree(简称ET)或第三方库lxml实现。以下是详细的操作指南:


​1. 解析XML​

​使用ElementTree​

import xml.etree.ElementTree as ET

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

# 遍历元素
for country in root.findall('country'):
    name = country.get('name')  # 获取属性
    rank = country.find('rank').text  # 获取子元素文本
    year = country.find('year').text
    print(f"{name}: Rank {rank}, Year {year}")

​处理命名空间​

namespaces = {'ns': 'http://example.com/ns'}
countries = root.findall('ns:country', namespaces=namespaces)

​2. 修改XML​

# 修改Singapore的排名
for country in root.findall('country'):
    if country.get('name') == 'Singapore':
        country.find('rank').text = '5'

# 保存修改后的XML(默认无缩进)
tree.write('data_modified.xml')

# 添加缩进(Python 3.9+)
root = ET.ElementTree(root).getroot()
ET.indent(root, space='    ')
tree.write('data_pretty.xml', encoding='utf-8', xml_declaration=True)

​3. 创建XML​

​从头构建​

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

# 添加子元素
country = ET.SubElement(root, 'country', name='USA')
ET.SubElement(country, 'rank').text = '1'
ET.SubElement(country, 'year').text = '2023'

# 生成XML文件
tree = ET.ElementTree(root)
tree.write('new_data.xml', encoding='utf-8', xml_declaration=True)

​使用lxml处理CDATA​

from lxml import etree

root = etree.Element('data')
country = etree.SubElement(root, 'country', name='UK')
description = etree.SubElement(country, 'description')
description.text = etree.CDATA('<p>Special characters & content</p>')

# 输出带缩进和CDATA的XML
tree = etree.ElementTree(root)
tree.write('cdata.xml', pretty_print=True, encoding='utf-8', xml_declaration=True)

​4. 高级操作​

​XPath查询(lxml支持完整XPath)​​

# 查找rank>3的国家
countries = root.xpath('//country[rank>3]')

​增量解析大文件​

for event, elem in ET.iterparse('large.xml', events=('end',)):
    if elem.tag == 'country':
        print(elem.find('rank').text)
        elem.clear()  # 释放内存

​5. 注意事项​

  • 安全性​:禁用实体解析防止XXE攻击。

    parser = ET.XMLParser(resolve_entities=False)
    tree = ET.parse('data.xml', parser=parser)
  • 缩进问题​:标准库ElementTree在Python 3.9+支持ET.indent(),低版本需手动处理或使用lxml。

  • 性能与功能​:需要复杂操作(如CDATA、完整XPath)时,优先使用lxml


​总结​

  • 基础场景​:使用xml.etree.ElementTree

  • 复杂需求​(CDATA、XPath、美化输出):选择lxml

  • 安全和大文件​:注意解析器配置和增量解析。