- Python 基础
- Python - 首页
- Python - 概述
- Python - 历史
- Python - 特性
- Python vs C++
- Python - Hello World 程序
- Python - 应用领域
- Python - 解释器
- Python - 环境搭建
- Python - 虚拟环境
- Python - 基本语法
- Python - 变量
- Python - 数据类型
- Python - 类型转换
- Python - Unicode 系统
- Python - 字面量
- Python - 运算符
- Python - 算术运算符
- Python - 比较运算符
- Python - 赋值运算符
- Python - 逻辑运算符
- Python - 位运算符
- Python - 成员运算符
- Python - 身份运算符
- Python - 运算符优先级
- Python - 注释
- Python - 用户输入
- Python - 数字
- Python - 布尔值
- Python 控制语句
- Python - 控制流
- Python - 决策制定
- Python - if 语句
- Python - if else
- Python - 嵌套 if
- Python - match-case 语句
- Python - 循环
- Python - for 循环
- Python - for-else 循环
- Python - while 循环
- Python - break 语句
- Python - continue 语句
- Python - pass 语句
- Python - 嵌套循环
- Python 函数与模块
- Python - 函数
- Python - 默认参数
- Python - 关键字参数
- Python - 仅限关键字参数
- Python - 位置参数
- Python - 仅限位置参数
- Python - 可变参数
- Python - 变量作用域
- Python - 函数注解
- Python - 模块
- Python - 内置函数
- Python 字符串
- Python - 字符串
- Python - 字符串切片
- Python - 修改字符串
- Python - 字符串连接
- Python - 字符串格式化
- Python - 转义字符
- Python - 字符串方法
- Python - 字符串练习
- Python 列表
- Python - 列表
- Python - 访问列表元素
- Python - 修改列表元素
- Python - 添加列表元素
- Python - 删除列表元素
- Python - 遍历列表
- Python - 列表推导式
- Python - 排序列表
- Python - 复制列表
- Python - 合并列表
- Python - 列表方法
- Python - 列表练习
- Python 元组
- Python - 元组
- Python - 访问元组元素
- Python - 更新元组
- Python - 解包元组
- Python - 遍历元组
- Python - 合并元组
- Python - 元组方法
- Python - 元组练习
- Python 集合
- Python - 集合
- Python - 访问集合元素
- Python - 添加集合元素
- Python - 删除集合元素
- Python - 遍历集合
- Python - 合并集合
- Python - 复制集合
- Python - 集合运算符
- Python - 集合方法
- Python - 集合练习
- Python 字典
- Python - 字典
- Python - 访问字典元素
- Python - 修改字典元素
- Python - 添加字典元素
- Python - 删除字典元素
- Python - 字典视图对象
- Python - 遍历字典
- Python - 复制字典
- Python - 嵌套字典
- Python - 字典方法
- Python - 字典练习
- Python 数组
- Python - 数组
- Python - 访问数组元素
- Python - 添加数组元素
- Python - 删除数组元素
- Python - 遍历数组
- Python - 复制数组
- Python - 反转数组
- Python - 排序数组
- Python - 合并数组
- Python - 数组方法
- Python - 数组练习
- Python 文件处理
- Python - 文件处理
- Python - 写入文件
- Python - 读取文件
- Python - 重命名和删除文件
- Python - 目录
- Python - 文件方法
- Python - OS 文件/目录方法
- Python - OS 路径方法
- 面向对象编程
- Python - OOPs 概念
- Python - 类与对象
- Python - 类属性
- Python - 类方法
- Python - 静态方法
- Python - 构造函数
- Python - 访问修饰符
- Python - 继承
- Python - 多态
- Python - 方法重写
- Python - 方法重载
- Python - 动态绑定
- Python - 动态类型
- Python - 抽象
- Python - 封装
- Python - 接口
- Python - 包
- Python - 内部类
- Python - 匿名类和对象
- Python - 单例类
- Python - 包装类
- Python - 枚举
- Python - 反射
- Python 错误与异常
- Python - 语法错误
- Python - 异常
- Python - try-except 块
- Python - try-finally 块
- Python - 抛出异常
- Python - 异常链
- Python - 嵌套 try 块
- Python - 用户自定义异常
- Python - 日志记录
- Python - 断言
- Python - 内置异常
- Python 多线程
- Python - 多线程
- Python - 线程生命周期
- Python - 创建线程
- Python - 启动线程
- Python - 加入线程
- Python - 线程命名
- Python - 线程调度
- Python - 线程池
- Python - 主线程
- Python - 线程优先级
- Python - 守护线程
- Python - 线程同步
- Python 同步
- Python - 线程间通信
- Python - 线程死锁
- Python - 中断线程
- Python 网络编程
- Python - 网络编程
- Python - Socket 编程
- Python - URL 处理
- Python - 泛型
- Python 库
- NumPy 教程
- Pandas 教程
- SciPy 教程
- Matplotlib 教程
- Django 教程
- OpenCV 教程
- Python 杂项
- Python - 日期与时间
- Python - 数学
- Python - 迭代器
- Python - 生成器
- Python - 闭包
- Python - 装饰器
- Python - 递归
- Python - 正则表达式
- Python - PIP
- Python - 数据库访问
- Python - 弱引用
- Python - 序列化
- Python - 模板
- Python - 输出格式化
- Python - 性能测量
- Python - 数据压缩
- Python - CGI 编程
- Python - XML 处理
- Python - GUI 编程
- Python - 命令行参数
- Python - 文档字符串
- Python - JSON
- Python - 发送邮件
- Python - 扩展
- Python - 工具/实用程序
- Python - GUIs
- Python 高级概念
- Python - 抽象基类
- Python - 自定义异常
- Python - 高阶函数
- Python - 对象内部
- Python - 内存管理
- Python - 元类
- Python - 使用元类进行元编程
- Python - 模拟和存根
- Python - 猴子补丁
- Python - 信号处理
- Python - 类型提示
- Python - 自动化教程
- Python - Humanize 包
- Python - 上下文管理器
- Python - 协程
- Python - 描述符
- Python - 诊断和修复内存泄漏
- Python - 不可变数据结构
- Python 资源
- Python - 问答
- Python - 在线测验
- Python - 快速指南
- Python - 参考
- Python - 速查表
- Python - 项目
- Python - 资源
- Python - 讨论
- Python 编译器
- NumPy 编译器
- Matplotlib 编译器
- SciPy 编译器
Python - XML 处理
XML 是一种可移植的开源语言,允许程序员开发可被其他应用程序读取的应用程序,而不管操作系统和/或开发语言。
什么是 XML?
可扩展标记语言 (XML) 是一种标记语言,类似于 HTML 或 SGML。这是万维网联盟推荐的开放标准。
XML 对于跟踪少量到中等量的数据非常有用,无需 SQL 后端。
XML 解析器架构和 API。
Python 标准库提供了一组最小但有用的接口来处理 XML。所有用于 XML 处理的子模块都位于 xml 包中。
xml.etree.ElementTree − ElementTree API,一个简单轻量级的 XML 处理器
xml.dom − DOM API 定义。
xml.dom.minidom − 最小的 DOM 实现。
xml.dom.pulldom − 支持构建部分 DOM 树。
xml.sax − SAX2 基类和实用函数。
xml.parsers.expat − Expat 解析器绑定。
用于 XML 数据的两个最基本和最广泛使用的 API 是 SAX 和 DOM 接口。
Simple API for XML (SAX) − 在这里,您注册感兴趣事件的回调,然后让解析器处理文档。当您的文档很大或内存有限时,这很有用,它在从磁盘读取文件时解析文件,并且整个文件永远不会存储在内存中。
Document Object Model (DOM) − 这是万维网联盟的推荐,其中整个文件被读取到内存中并以分层(基于树)的形式存储,以表示 XML 文档的所有特征。
处理大型文件时,SAX 的处理速度显然不如 DOM。另一方面,仅使用 DOM 会严重消耗您的资源,尤其是在处理许多小型文件时。
SAX 是只读的,而 DOM 允许更改 XML 文件。由于这两个不同的 API 彼此互补,因此您无需理由不能将它们都用于大型项目。
对于我们所有的 XML 代码示例,让我们使用一个简单的 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 解析的标准接口。使用 SAX 解析 XML 通常需要您通过子类化 `xml.sax.ContentHandler` 来创建自己的 `ContentHandler`。
您的 `ContentHandler` 处理您所使用的 XML 格式的特定标签和属性。`ContentHandler` 对象提供方法来处理各种解析事件。其所属的解析器在解析 XML 文件时会调用 `ContentHandler` 方法。
`startDocument` 和 `endDocument` 方法分别在 XML 文件的开头和结尾处调用。`characters(text)` 方法通过参数 `text` 传递 XML 文件的字符数据。
在每个元素的开始和结束处都会调用 `ContentHandler`。如果解析器不是命名空间模式,则调用 `startElement(tag, attributes)` 和 `endElement(tag)` 方法;否则,将调用相应的 `startElementNS` 和 `endElementNS` 方法。这里,`tag` 是元素标签,`attributes` 是一个 `Attributes` 对象。
在继续之前,还需要了解其他一些重要的方法:
`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` − 如果指定,`errorhandler` 必须是一个 SAX `ErrorHandler` 对象。
`parseString` 方法
还有一个方法可以创建一个 SAX 解析器并解析指定的 XML 字符串。
xml.sax.parseString(xmlstring, contenthandler[, errorhandler])
以下是参数的详细信息:
`xmlstring` − 要从中读取的 XML 字符串的名称。
`contenthandler` − 这必须是一个 `ContentHandler` 对象。
`errorhandler` − 如果指定,`errorhandler` 必须是一个 SAX `ErrorHandler` 对象。
示例
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 = "" # Call when an element starts def startElement(self, tag, attributes): self.CurrentData = tag if tag == "movie": print ("*****Movie*****") title = attributes["title"] print ("Title:", title) # Call when an elements ends 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 = "" # Call when a character is read 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__"): # create an XMLReader parser = xml.sax.make_parser() # turn off namepsaces parser.setFeature(xml.sax.handler.feature_namespaces, 0) # override the default ContextHandler 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 API。
使用 DOM API 解析 XML
文档对象模型 (“DOM”) 是万维网联盟 (W3C) 提供的一种跨语言 API,用于访问和修改 XML 文档。
DOM 对于随机访问应用程序非常有用。SAX 每次只允许您查看文档的一小部分。如果您查看一个 SAX 元素,则无法访问其他元素。
以下是快速加载 XML 文档并使用 `xml.dom` 模块创建 `minidom` 对象的最简单方法。`minidom` 对象提供了一个简单的解析器方法,可以快速从 XML 文件创建 DOM 树。
示例短语调用 `minidom` 对象的 `parse(file [,parser])` 函数来解析由 `file` 指定的 XML 文件到一个 DOM 树对象。
from xml.dom.minidom import parse import xml.dom.minidom # Open XML document using minidom parser DOMTree = xml.dom.minidom.parse("movies.xml") collection = DOMTree.documentElement if collection.hasAttribute("shelf"): print ("Root element : %s" % collection.getAttribute("shelf")) # Get all the movies in the collection movies = collection.getElementsByTagName("movie") # Print detail of each 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 API。
ElementTree XML API
`xml` 包有一个 `ElementTree` 模块。这是一个简单且轻量级的 XML 处理器 API。
XML 是一种树状的层次数据格式。此模块中的“ElementTree”将整个 XML 文档视为一棵树。“Element”类表示此树中的单个节点。对 XML 文件的读写操作在 ElementTree 级别进行。与单个 XML 元素及其子元素的交互在 Element 级别进行。
创建 XML 文件
这棵树是从根元素开始,然后是其他元素的元素层次结构。每个元素都是使用此模块的 `Element()` 函数创建的。
import xml.etree.ElementTree as et e=et.Element('name')
每个元素都具有一个标签和一个 `attrib` 属性,后者是一个 `dict` 对象。对于树的起始元素,`attrib` 是一个空字典。
>>> root=xml.Element('employees') >>> root.tag 'employees' >>> root.attrib {}
您现在可以设置一个或多个子元素添加到根元素下。每个子元素可能具有一个或多个子元素。使用 `SubElement()` 函数添加它们并定义其文本属性。
child=xml.Element("employee") nm = xml.SubElement(child, "name") nm.text = student.get('name') age = xml.SubElement(child, "salary") age.text = str(student.get('salary'))
每个子元素都使用 `append()` 函数添加到根元素中,如下所示:
root.append(child)
添加所需数量的子元素后,使用 `elementTree()` 函数构造一个树对象:
tree = et.ElementTree(root)
整个树结构由树对象的 `write()` 函数写入二进制文件:
f=open('employees.xml', "wb") tree.write(f)
示例
在这个例子中,一个树是由一个字典项列表构成的。每个字典项都包含描述学生数据结构的键值对。这样构造的树被写入“myfile.xml”。
import xml.etree.ElementTree as et employees=[{'name':'aaa','age':21,'sal':5000},{'name':xyz,'age':22,'sal':6000}] root = et.Element("employees") for employee in employees: child=xml.Element("employee") root.append(child) nm = xml.SubElement(child, "name") nm.text = student.get('name') age = xml.SubElement(child, "age") age.text = str(student.get('age')) sal=xml.SubElement(child, "sal") sal.text=str(student.get('sal')) tree = et.ElementTree(root) with open('employees.xml', "wb") as fh: tree.write(fh)
“myfile.xml”存储在当前工作目录中。
<employees><employee><name>aaa</name><age>21</age><sal>5000</sal></employee><employee><name>xyz</name><age>22</age><sal>60</sal></employee></employee>
解析 XML 文件
现在让我们读取上面示例中创建的“myfile.xml”。为此,将使用 `ElementTree` 模块中的以下函数:
`ElementTree()` − 此函数被重载以将元素的层次结构读取到树对象中。
tree = et.ElementTree(file='students.xml')
`getroot()` − 此函数返回树的根元素。
root = tree.getroot()
您可以获得元素下一级子元素的列表。
children = list(root)
在下面的示例中,“myfile.xml”的元素和子元素被解析成一个字典项列表。
示例
import xml.etree.ElementTree as et tree = et.ElementTree(file='employees.xml') root = tree.getroot() employees=[] children = list(root) for child in children: employee={} pairs = list(child) for pair in pairs: employee[pair.tag]=pair.text employees.append(employee) print (employees)
它将产生以下输出:
[{'name': 'aaa', 'age': '21', 'sal': '5000'}, {'name': 'xyz', 'age':'22', 'sal': '6000'}]
修改 XML 文件
我们将使用 `Element` 的 `iter()` 函数。它为给定标签创建一个树迭代器,当前元素作为根。迭代器按文档(深度优先)顺序迭代此元素及其下方的所有元素。
让我们为所有“marks”子元素构建迭代器,并将每个“sal”标签的文本增加 100。
import xml.etree.ElementTree as et tree = et.ElementTree(file='students.xml') root = tree.getroot() for x in root.iter('sal'): s=int (x.text) s=s+100 x.text=str(s) with open("employees.xml", "wb") as fh: tree.write(fh)
我们的“employees.xml”现在将相应地修改。我们也可以使用 `set()` 来更新特定键的值。
x.set(marks, str(mark))