1 XML简单介绍
1.1 XML简单介绍
XML(eXtensible Markup Language
):
可扩展标记语言
:被设计用来传输
和存储
数据
常见的XML编程接口有DOM和SAX,这两种接口处理XML文件的方式不同。
python有三种方法解析XML
文件参考:
SAX(simple API for XML)
:DOM(Document Object Model)
:将XML数据
映射到内存中(比较慢、耗内存
),解析成一个树,通过对树的操作XMLElementTree(元素树)
:ElementTree像一个轻量级的DOM,具有方便友好的API,大妈可用性好,速度快,内存消耗少。
1.2 XML语法结构
下面主要以ElementTree来讲解如何解析一个xml文件
2 XML.etree.ElementTree的使用
测试的xml文件:test.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>
import xml.etree.ElementTree as ET
2.1 读取xml文件,然后返回根元素
ET.parse()接受参数可以是xml文件路径,也可以是读取xml的文件句柄
parse(source: {read}, parser: Any = None) -> ElementTree
- ET.parse():接受参数为xml文件路径
```python
import xml.etree.ElementTree as ET
tree = ET.parse('./test.xml')
root = tree.getroot()
print(type(root), root)
* ET.parse():接受参数为读取xml的文件句柄
```python
import xml.etree.ElementTree as ET
tree = ET.parse(open('./test.xml'))
root = tree.getroot()
print(root)
# <Element 'data' at 0x00000243ECFE5958>
2.2 获取子元素及子元素属性
作为元素Element,如果有子元素
- 可以使用
tag属性
获取子元素名
,元素名
以字符串
返回 - 可以使用
attrib属性
获取子元素中定义的属性
,属性
以字典键值对
返回for child in root: print(child.tag, child.attrib) print(type(child.tag), type(child.attrib)) ''' country {'name': 'Liechtenstein'} <class 'str'> <class 'dict'> country {'name': 'Singapore'} <class 'str'> <class 'dict'> country {'name': 'Panama'} <class 'str'> <class 'dict'> '''
2.3 获取元素标签中存储的数据
使用
text属性
可以获取元素标签
中存储
的数据
,使用text属性
返回的是字符串类型
print(root.tag) print(root.attrib) # 根标签元素中没有属性,因此返回一个空字典 print(root[0]) print(root[0].text, type(root[0].text)) print(root[0][1]) # root根元素的第一个子元素标签是country,然后country的子元素的第二个元素 print(root[0][1].text, type(root[0][1].text)) ''' data {} <Element 'country' at 0x0000018269E1F9A8> <class 'str'> <Element 'year' at 0x00000274B9790A48> 2008 <class 'str'> '''
2.4 查找指定元素标签中存储的数据
Element.iter() 方法
可以递归遍历
其下所有子树
(包括子级、子级的子级等)
如下:递归的找到根元素下所有的 'neighbor'元素
for neighbor in root.iter('neighbor'):
# print(neighbor.tag) # 输出都是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'}
'''
1、查找指定元素中存储的数据
rootElement.find('childElement_name')
:返回子元素中存储的数据,返回类型字符串
2、获取中元素的属性的属性值
rootElement.get('rootElementAttrib_name')
:返回元素属性的值,返回类型字符串
for country in root.iter('country'):
# 查找country元素下的子元素rank,然后输出rank元素中存储的值
# contry.find('rank'):find()方法是查找country元素的子元素rank存储的值
rank = country.find('rank').text
print(type(rank), rank)
# country.get('name'):get()方法是获取元素country中属性name对应的属性值
name = country.get('name')
print(type(name), name)
'''
<class 'str'> 1
<class 'str'> 4
<class 'str'> 68
'''
2.5 修改XML文件
2.5.1 修改xml文件
- 修改元素存储数据:使用text属性
- 修改元素的属性:使用Element.set()方法
```python
for rank in root.iter('rank'):
new_rank = int(rank.text) + 1 # rank元素标签中存储的值加1
rank.text = str(new_rank) # 转换成字符串类型
rank.set('update', 'yes') # 给rank元素设置属性 update="yes"
tree.write('output.xml')
修改之后的文件如下:
```python
<?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>
<country name="Panama">
<rank updated="yes">69</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>
2.5.1 删除xml文件中一些元素
Element.remove()
删除元素。假设我们要删除排名高于50的所有国家/地区:
for country in root.findall('country'):
rank = int(country.find('rank').text)
if rank > 50:
root.remove(country)
tree.write('output2.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>