xml.etree ElementTree简介
xml.etree ElementTree介绍
ET简介
ET有重要的两个类,一个是ElementTree,另一个是Element.
ET使用
假设有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>
解析xml:
导入数据或者文件:parse(source, parser=None)
获取xml根:tree.getroot()
解析字符串并获取根:ET.fromstring(country_data_as_string)
parse(source, parser=None)
#source:xml文件
#parser:选择解释器实例,默认XMLParser
#读入文件
tree = ET.parse('country_data.xml')
root = tree.getroot() #获取根
#解析字符串获取根
root = ET.fromstring(country_data_as_string)
root的属性
root有一个标记和一个属性字典。
>>> root.tag
'data' #这个是标签名
>>> root.attrib
{} #这个是标签属性
遍历节点孩子的标签名和属性
>>> for child in root:
... print(child.tag, child.attrib)
...
country {'name': 'Liechtenstein'}
country {'name': 'Singapore'}
country {'name': 'Panama'}
**通过下标锁定元素
root是根节点,root[0]是根节点下的第一个元素,root[0] [1]是根节点的第一个节点的第二个元素
>>> root[0][1].text
'2008'
获取子元素迭代器
通过Element.iter()可以获取到某元素的子元素的迭代器,如:root.iter(‘neighbor’)获取根元素下的名为neighbor的元素的迭代器
>>> for neighbor in root.iter('neighbor'):
... print(neighbor.attrib)
...
{'name': 'Austria', 'direction': 'E'}
{'name': 'Switzerland', 'direction': 'W'}
{'name': 'Malaysia', 'direction': 'N'}
{'name': 'Costa Rica', 'direction': 'W'}
{'name': 'Colombia', 'direction': 'E'}
查找节点(元素)
Element.findall()只查找带有标记的节点,这些元素是当前节点的直接子节点。
Element.text访问节点的文本内容
Element.find()查找第一个指定便签的子节点
Element.get()获取节点属性
>>> for country in root.findall('country'):
... rank = country.find('rank').text
... name = country.get('name')
... print(name, rank)
...
Liechtenstein 1
Singapore 4
Panama 68
更改节点信息
ElementTree.write()写入并创建xml文件
Element.set()给节点设置属性
Element.append()给节点添加新的子节点
>>> for rank in root.iter('rank'):
... new_rank = int(rank.text) + 1
... rank.text = str(new_rank)
... rank.set('updated', 'yes')
...
>>> tree.write('output.xml')
移除节点
Element.remove()能移除整个节点,包括它的子节点。
>>> for country in root.findall('country'):
... rank = int(country.find('rank').text)
... if rank > 50:
... root.remove(country)
...
>>> tree.write('output.xml')
XML文件将变成:(这里删除了一个节点,包括它的子节点)
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
</data>
构建XML文件
ET.Element()创建一个节点
ET.SubElement()创建子节点
>>> a = ET.Element('a')
>>> b = ET.SubElement(a, 'b')
>>> c = ET.SubElement(a, 'c')
>>> d = ET.SubElement(c, 'd')
>>> ET.dump(a)
<a><b /><c><d /></c></a>
xpath表达式
ET支持xpath表达式,xpath是用来分析XML/HTML文件或数据的。我们可以通过xpath表达式来快速得锁定HTML/XML的节点或元素。在HTML中标签通常称为节点。(有一点值得注意的是,在ET中有部分xpath表达式不能直接使用)
这里就简单介绍一下xpath语法。
xpath语法
简单的语法
/ #根节点或节点间的过渡
// #跨越节点获取节点
. #选取当前节点
.. #当前节点的父节点(在ET中不能通过子节点直接获取父节点)
@ #选取属性
text() #选取文本(在ET中不能使用)
[index] #根据index获取第index个标签(index从1开始)
[@Classname] #根据属性名获取标签
contains(p,content) #模糊查询(p定位,content匹配字段)
xpath有点像文件路径的写法,很容易学习,下面的简单例子能帮助理解。
简单的例子
#根节点下的html的标签中的body标签中的div标签中的div标签
/html/body/div/div
#获取所以a标签
//a
#获取html的标签中的body标签中的所有a标签(可以跨越节点,不必一定是子节点)
/html/body//a
#在当前节点下的a标签
./a
#当前节点的父标签中的a标签
../a
#根节点下的html的标签中的body标签中的a标签中的class属性
/html/body/a/@class
#li便签下的第3个li标签
//li[3]
#通过属性定位
//a[@href=""]
#html的标签中的body标签中的a标签中的文本内容
/html/body/a/text()
#获取a标签,并且属性name中有字段"myname"
//a[contains(@name,"myname")]
其他xpath博客连接: https://blog.csdn.net/qq_43203949/article/details/108203340.
在ET上使用xpath
如果学过parsel模块包的,把findall()当成extract()或者getall()方法就可以了。
import xml.etree.ElementTree as ET
root = ET.fromstring(countrydata)
# Top-level elements(当前节点就是根节点)
root.findall(".")
# All 'neighbor' grand-children of 'country' children of the top-level
# elements
root.findall("./country/neighbor")
# Nodes with name='Singapore' that have a 'year' child
root.findall(".//year/..[@name='Singapore']")
# 'year' nodes that are children of nodes with name='Singapore'
root.findall(".//*[@name='Singapore']/year")
# All 'neighbor' nodes that are the second child of their parent
root.findall(".//neighbor[2]")
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)