[Python3]XML解析处理 - Element Tree
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Python3]XML解析处理 - Element Tree相关的知识,希望对你有一定的参考价值。
概述
本文就是python xml解析进行讲解,在python中解析xml有很多种方法,本文通过实例来讲解如何使用ElementTree来解析xml。对于其他的xml解析方法,请自行去查找资料。
请注意,本文不是ElementTree手册,不会将所有的特性进行演示,笔者从实际用到的一些关键特性进行实例演示,对于其他特性,大家可以参见官方文档学习和了解:
https://docs.python.org/3/library/xml.etree.elementtree.html
什么是ElementTree
ElementTree是Python提供解析xml的标准库,ElementTree中每个节点(即Element)具有如下属性:
-
tag: string对象,标识该元素类型
-
attrib:dictionnary对象,标识该元素属性
-
text:string对象,标识该元素的文本
-
tail:string对象,标识该元素可选的尾字符串
-
child elements: 标识子节点
注:Element类型是一种灵活的容器对象,用于在内存中存储结构化数据。
使用ElementTree的标准方式为:
try: # 若想加快速度,可以使用C语言编译的API xml.etree.cElementTree。 import xml.etree.cElementTree as ET except ImportError: import xml.etree.ElementTree as ET
或者直接:
import xml.etree.ElementTree as ET
从文件加载xml进行解析
本节通过加载一个已存在于硬盘的xml文件,示例演示,直接看代码。
将下列内容保存至本地任何目录下: data_demo.xml:
<?xml version="1.0"?> <data> <country name="Liechtenstein"> <rank>1</rank> <year>2008</year> <gdppc>141100</gdppc> <neighbor name="Austria" direction="E"/> <neighbor name="Switzerland" direction="W"/> </country> <country name="Singapore"> <rank>4</rank> <year>2011</year> <gdppc>59900</gdppc> <neighbor name="Malaysia" direction="N"/> </country> <country name="Panama"> <rank>68</rank> <year>2011</year> <gdppc>13600</gdppc> <neighbor name="Costa Rica" direction="W"/> <neighbor name="Colombia" direction="E"/> </country> </data>
下面我们解析上述data_demo.xml文档进行读、增、修改、删除操作
# -*- coding:utf-8 -*- __author__ = ‘谷白‘ try: # 若想加快速度,可以使用C语言编译的API xml.etree.cElementTree。 import xml.etree.cElementTree as ET except ImportError: import xml.etree.ElementTree as ET if __name__ == "__main__": print("解析本地data_demo.xml文档") # 加载xml文件 tree = ET.parse("data_demo.xml") # 获取根节点, 并打印节点文本:data root = tree.getroot() print(root.tag) # 遍历输出country及其name属性 for child in root: print(child.tag, "name:" ,child.attrib["name"]) # 遍历rank节点 # 我们借助iter迭代器来进行全迭代查找感兴趣的节点 # 输出节点tag及其文本 print("使用iter迭代器查找目标节点") for rank in root.iter("rank"): print(rank.tag, " - ", rank.text) # 换一种方式来遍历rank节点 # 我们借助findall和find方法来查找感兴趣的节点 # 输出节点tag及其文本 # 注意:findall只能查找从当前节点的子节点查找目标节点 print("使用findall查找目标节点") # 使用findall查找所有country节点,用于遍历 for country in root.findall("country"): #print(country) # 使用find从country节点中查找rank节点 rank = country.find("rank") print(rank.tag, " - ", rank.text) # 把所有的rank的文本都修改为: 博客园谷白 for rank in root.iter("rank"): rank.text = "博客园谷白" rank.set(‘updated‘, ‘yes‘) # 把修改后的rank的文本重新遍历打印出来,这时应该打印出: 博客园谷白 for rank in root.iter("rank"): print(rank.text) # 给所有的country新增一个<url>www.testingunion.com</url>节点 for country in root.iter("country"): # 创建一个节点 url = ET.Element("url") #print(url) # 给节点url的text赋值 url.text = "www.testingunion.com" # 将url节点追加到country节点下 country.append(url) # 打印下整个xml出来看看是不是所有country节点都新增了一个url节点 for country in root.iter("country"): # 查找url节点 url = country.find("url") # 打印url的text print(url.text) # 删除year节点 for country in root.iter("country"): year = country.find("year") # 如果year节点存在,则删除 if year is not None: print("删除了一个year节点") country.remove(year) # 保存上述 修改、新增、删除后的xml到 data_demo_new.xml中 # 大家自己打开data_demo_new.xml文档看修改、新增、删除的节点是否有效 tree.write("data_demo_new.xml", encoding="utf-8")
注: 用ET.fromstring("xml格式字符串") 替换ET.parse("data_demo.xml"),后续其他代码不变,即可实现对xml格式的字符串进行遍历读取、新增、修改和删除动作。
xpath支持
通过上面的实例我们基本学会了怎么对xml文档/xml格式的字符串进行遍历、新增、修改和删除操作,但对于xml怎么能缺少xpath的支持。
在ElementTree中,提供了良好的xpath特性支持,下面看一个实例
# -*- coding:utf-8 -*- __author__ = ‘谷白‘ try: # 若想加快速度,可以使用C语言编译的API xml.etree.cElementTree。 import xml.etree.cElementTree as ET except ImportError: import xml.etree.ElementTree as ET if __name__ == "__main__": print("Element Tree XPath特性支持示例") # 加载xml文件 tree = ET.parse("data_demo.xml") # 获取根节点, 并打印节点文本:data root = tree.getroot() # 选择当前节点, 返回的是当前节点对象列表 print("选择当前节点") data = root.findall(".") for d in data: print(d.tag) # 选择所有country节点 print("选择所有country节点方法一") countrys = root.findall(".//country") for country in countrys: print(country.tag, " ", country.attrib["name"]) print("选择所有country节点方法二") countrys = root.findall("country") for country in countrys: print(country.tag, " ", country.attrib["name"]) print("选择name属性为Panama的country节点") countrys = root.findall(".//*[@name=‘Panama‘]") for country in countrys: print(country.tag, " ", country.attrib["name"]) # name属性为Panama的country下的year节点 print("name属性为Panama的country下的year节点") years = root.findall(".//country[@name=‘Panama‘]/year") for year in years: print(year.text) # 通过索引来选择country节点,选择第一个country节点 # 注意索引从 1 开始 print("通过索引来选择country节点,选择第一个country节点") country = root.findall(".//country[1]") for c in country: print(c.tag, " ", c.attrib["name"]) # 通过子节点的文本内容来选择节点 # 选择子节点gdppc且其文本为59900 的country节点 # 请注意这返回的是gdppc的父节点 print("通过子节点的文本内容来选择节点") gdppc = root.findall(".//*[gdppc=‘59900‘]") for gd in gdppc: print(gd.tag)
小结
本文就ElementTree解析xml的遍历、新增、修改、删除等操作进行了实例演示,并演示了其对XPath选择器的支持,但要注意的是其对XPath的支持是有限制的,并不支持所有的XPath语法。
以上是关于[Python3]XML解析处理 - Element Tree的主要内容,如果未能解决你的问题,请参考以下文章