Python XML 处理指南:实现跨平台数据互操作
XML 是一种可移植的开源语言,让程序员开发的应用可被其他应用读取,跨操作系统和开发语言。
什么是 XML?
可扩展标记语言 (XML) 类似 HTML 或 SGML,由 W3C 推荐并作为开放标准发布。XML 适合跟踪中小量数据,无需 SQL 数据库支撑。
XML 解析器架构与 API
Python 标准库提供处理 XML 的基本接口。两大主流 API:
- SAX (Simple API for XML):注册感兴趣事件的回调,解析器逐步读取文档。适合大文档或内存受限场景,边读边解析,不将整个文件加载内存。
- DOM (Document Object Model) API:W3C 推荐,整个文件读入内存并以层次化(树)形式存储,完整呈现 XML 文档特征。
大文件时 SAX 处理速度不如 DOM;但大量小文件独占 DOM 会耗尽资源。SAX 只读,DOM 允许修改 XML。两者互补,大型项目可结合使用。
示例使用 movies.xml 作为输入:
<collection shelf="New Arrivals">
<movie title="Enemy Behind">
<type>War, Thriller</type>
<format>DVD</format>
<year>2003</year>
<rating>PG</rating>
<stars>10</stars>
<description>Talk about a US-Japan war</description>
</movie>
<movie title="Transformers">
<type>Anime, Science Fiction</type>
<format>DVD</format>
<year>1989</year>
<rating>R</rating>
<stars>8</stars>
<description>A schientific fiction</description>
</movie>
<movie title="Trigun">
<type>Anime, Action</type>
<format>DVD</format>
<episodes>4</episodes>
<rating>PG</rating>
<stars>10</stars>
<description>Vash the Stampede!</description>
</movie>
<movie title="Ishtar">
<type>Comedy</type>
<format>VHS</format>
<rating>PG</rating>
<stars>2</stars>
<description>Viewable boredom</description>
</movie>
</collection>
使用 SAX API 解析 XML
SAX 是事件驱动 XML 解析的标准接口。通常需继承 xml.sax.ContentHandler 创建自定义 ContentHandler。
ContentHandler 处理特定标签和属性。解析器解析 XML 文件时调用 ContentHandler 方法。startDocument 和 endDocument 在文件开始和结束时调用。characters(text) 接收字符数据。元素开始和结束时调用 startElement(tag, attributes) 和 endElement(tag)(非命名空间模式),否则调用 startElementNS 和 endElementNS。
make_parser 方法
创建并返回新解析器对象,类型为系统找到的第一个解析器类型。
xml.sax.make_parser([parser_list])
参数:parser_list 可选,解析器列表,必须实现 make_parser 方法。
parse 方法
创建 SAX 解析器并解析文档。
xml.sax.parse(xmlfile, contenthandler[, errorhandler])
参数:xmlfile XML 文件名;contenthandler ContentHandler 对象;errorhandler 可选 SAX ErrorHandler 对象。
parseString 方法
解析 XML 字符串。
xml.sax.parseString(xmlstring, contenthandler[, errorhandler])
示例
#!/usr/bin/python
import xml.sax
class MovieHandler(xml.sax.ContentHandler):
def __init__(self):
self.CurrentData = ""
self.type = ""
self.format = ""
self.year = ""
self.rating = ""
self.stars = ""
self.description = ""
def startElement(self, tag, attributes):
self.CurrentData = tag
if tag == "movie":
print("*****Movie*****")
title = attributes["title"]
print("Title:", title)
def endElement(self, tag):
if self.CurrentData == "type":
print("Type:", self.type)
elif self.CurrentData == "format":
print("Format:", self.format)
elif self.CurrentData == "year":
print("Year:", self.year)
elif self.CurrentData == "rating":
print("Rating:", self.rating)
elif self.CurrentData == "stars":
print("Stars:", self.stars)
elif self.CurrentData == "description":
print("Description:", self.description)
self.CurrentData = ""
def characters(self, content):
if self.CurrentData == "type":
self.type = content
elif self.CurrentData == "format":
self.format = content
elif self.CurrentData == "year":
self.year = content
elif self.CurrentData == "rating":
self.rating = content
elif self.CurrentData == "stars":
self.stars = content
elif self.CurrentData == "description":
self.description = content
if __name__ == "__main__":
parser = xml.sax.make_parser()
parser.setFeature(xml.sax.handler.feature_namespaces, 0)
Handler = MovieHandler()
parser.setContentHandler(Handler)
parser.parse("movies.xml")
输出:
*****Movie*****
Title: Enemy Behind
Type: War, Thriller
Format: DVD
Year: 2003
Rating: PG
Stars: 10
Description: Talk about a US-Japan war
*****Movie*****
Title: Transformers
Type: Anime, Science Fiction
Format: DVD
Year: 1989
Rating: R
Stars: 8
Description: A schientific fiction
*****Movie*****
Title: Trigun
Type: Anime, Action
Format: DVD
Rating: PG
Stars: 10
Description: Vash the Stampede!
*****Movie*****
Title: Ishtar
Type: Comedy
Format: VHS
Rating: PG
Stars: 2
Description: Viewable boredom
完整 SAX API 文档请参考 Python 标准 SAX APIs。
使用 DOM API 解析 XML
DOM 是 W3C 跨语言 API,用于访问和修改 XML 文档。适合随机访问应用。SAX 一次只能看文档一小部分,DOM 则可随意访问任意节点。
使用 xml.dom.minidom 快速加载 XML 并创建 minidom 对象,其 parse(file[, parser]) 方法将 XML 文件解析为 DOM 树对象。
#!/usr/bin/python
from xml.dom.minidom import parse
import xml.dom.minidom
DOMTree = xml.dom.minidom.parse("movies.xml")
collection = DOMTree.documentElement
if collection.hasAttribute("shelf"):
print("Root element : %s" % collection.getAttribute("shelf"))
movies = collection.getElementsByTagName("movie")
for movie in movies:
print("*****Movie*****")
if movie.hasAttribute("title"):
print("Title: %s" % movie.getAttribute("title"))
type = movie.getElementsByTagName('type')[0]
print("Type: %s" % type.childNodes[0].data)
format = movie.getElementsByTagName('format')[0]
print("Format: %s" % format.childNodes[0].data)
rating = movie.getElementsByTagName('rating')[0]
print("Rating: %s" % rating.childNodes[0].data)
description = movie.getElementsByTagName('description')[0]
print("Description: %s" % description.childNodes[0].data)
输出:
Root element : New Arrivals
*****Movie*****
Title: Enemy Behind
Type: War, Thriller
Format: DVD
Rating: PG
Description: Talk about a US-Japan war
*****Movie*****
Title: Transformers
Type: Anime, Science Fiction
Format: DVD
Rating: R
Description: A schientific fiction
*****Movie*****
Title: Trigun
Type: Anime, Action
Format: DVD
Rating: PG
Description: Vash the Stampede!
*****Movie*****
Title: Ishtar
Type: Comedy
Format: VHS
Rating: PG
Description: Viewable boredom
完整 DOM API 文档请参考 Python 标准 DOM APIs。
Python
- 精通Python数据类型:实战指南
- 精通Python运算符:全面指南
- 精通Python Pass语句:实战指南
- 精通Python函数参数:位置、关键字与默认参数
- 精通 Python 字典:创建、操作与进阶技巧
- 精通 Python 迭代器:工作原理与自定义构建
- Python 闭包详解:嵌套函数如何捕获变量
- 精通 Python datetime:日期、时间与时区实战指南
- 精通 Python time.sleep():最佳实践、多线程与实战案例
- Python 语言概览:高级、可读、交互式与面向对象
- Python 数字类型详解:不可变数值数据的操作与数学函数
- Python 字符串完全指南:创建、访问、格式化与内置方法大全