Python3 XML 解析

XML(可扩展标记语言)用成对的尖括号标签描述带层次的数据,常见于配置文件、老系统接口与 Android 资源等场景。Python 标准库 xml.etree.ElementTree 可把 XML 读成树状结构,再遍历节点取值。

XML 结构示例

根元素是 booklist,其下每个 book 是子元素,书名是孙元素,属性写在开始标签里。把下面内容存为 books.xml 备用:

<?xml version="1.0" encoding="utf-8"?>
<booklist>
  <book id="1">
    <name>Python 入门</name>
    <price>59.0</price>
  </book>
  <book id="2">
    <name>算法图解</name>
    <price>49.0</price>
  </book>
</booklist>

解析 XML 文件

ET.parse 读文件、getroot 取根元素,节点.tag 是标签名、.text 是文本、.get() 取属性:

import xml.etree.ElementTree as ET

tree = ET.parse('books.xml')     # 从文件解析
root = tree.getroot()
print(root.tag)                  # 输出:booklist
print(root.find('book').get('id'))   # 输出:1
print(root.find('book/name').text)   # 输出:Python 入门

findall 遍历同名节点

import xml.etree.ElementTree as ET

root = ET.parse('books.xml').getroot()
for book in root.findall('book'):            # 找所有 book 子节点
    print(book.get('id'), book.find('name').text)
# 输出:1 Python 入门
# 输出:2 算法图解

iter 递归遍历

find/findall 只查直接子级,iter 则无视层级、遍历树中所有指定标签:

import xml.etree.ElementTree as ET

root = ET.parse('books.xml').getroot()
for name in root.iter('name'):     # 任意层级的 name
    print(name.text)
# 输出:Python 入门
# 输出:算法图解

从字符串解析

XML 不在文件里时,可用 ET.fromstring 直接解析字符串:

import xml.etree.ElementTree as ET

s = '<user><name>张三</name><age>25</age></user>'
root = ET.fromstring(s)
print(root.find('name').text)      # 输出:张三

创建与写入 XML

也可以反向生成 XML 并保存(ElementTree(root).write 写入文件):

import xml.etree.ElementTree as ET

root = ET.Element('booklist')
book = ET.SubElement(root, 'book', {'id': '3'})
ET.SubElement(book, 'name').text = '流畅的 Python'
ET.SubElement(book, 'price').text = '99.0'
ET.ElementTree(root).write('new.xml', encoding='utf-8', xml_declaration=True)

与 JSON 对比

对比项XMLJSON
数据结构标签树,可含属性键值对 / 数组
冗余度较高较低、省流量
可读性一般较好
解析速度较慢较快
适用场景配置、遗留系统Web 接口主流

如今 Web 接口普遍用 JSON,XML 多出现在遗留系统和特定行业协议中。

小结

解析 XML 三步走:ET.parse 读文件、getroot 拿根元素、find/findall/iter 找节点,再用 .text 与 .get() 读内容与属性;新项目做数据交换优先考虑 JSON。

笔记加载中…