1. tag 标签:string对象,表示数据代表的种类。
2. attrib 属性:dictionary对象,表示附有的属性。
3. text:string对象,表示element的内容。
4. tail:string对象,表示element闭合之后的尾迹。
5. 若干子元素(child elements)。
Python 中处理 xml 文件有三种方式:
xml.dom:适合用于处理 DOM API。它能够将 XML 数据在内存中解析成一个树,然后通过对树的操作来操作 XML。但是这种方式由于将 XML 数据映射到内存中的树,导致比较慢,且消耗更多内存
xml.sax:Python 标准库包含 SAX 解析器,SAX 用事件驱动模型,通过在解析 XML 的过程中触发一个个的事件并调用用户定义的回调函数来处理 XML 文件。
xml.etree.ElementTree 就像一个轻量级的 DOM,具有方便友好的 API。代码可用性好,速度快,消耗内存少。
注:
因DOM需要将 XML 数据映射到内存中的树,一是比较慢,二是比较耗内存,而 SAX 流式读取 XML 文件,比较快,占用内存少,但需要用户实现回调函数(handler)
Python 中 ElementTree 模块
ElementTree 是 Python 中内置的模块
通过 import xml.etree.ElementTree 导入
ElementTree 模块中属性方法,如下
tag 获取节点名称
attrib 属性
text 文本
tail 附加文本
可以通过索引取值操作获取子节点
<
gdppc1
>
141100
</
gdppc1
>
test
<
neighbor1
name
="Austria"
direction
="E"
/>
<
neighbor1
name
="Switzerland"
direction
="W"
/>
</
country1
>
<
country2
name
="Singapore"
>
<
rank2
updated
="no"
>
5
</
rank2
>
<
year2
>
2011
</
year2
>
<
gdppc2
>
59900
</
gdppc2
>
<
neighbor2
name
="Malaysia"
direction
="N"
/>
</
country2
>
</
data
>
import xml.etree.ElementTree as ET
et = ET.parse("xmlfile")
root = et.getroot()
print(root.tag) # data
print(root[0].tag) # country1
print(root[1].tag) # country2
print(root[0].attrib) # {'name': 'Liechtenstein'}
print(root[0][1].text) # 2008
print(root[0][2].tail) # test
for r in root:
print(r.tag)
# 结果如下
country1
country2
ElementTree 模块中 ElementTree 类方法,如下
parse(source,parser=None) 将外部 XML 文件加载到元素树中。source 是一个文件名或文件对象。Parser 是一个可选的解析器实例。如果没有给出,则使用标准 XMLParse r解析器。返回一个 ElementTree 实例。
getroot() 返回此树的根元素
write(file, encoding="us-ascii", xml_declaration=None, default_namespace=None, method="xml", *, short_empty_elements=True)
将元素树作为 XML 写入文件。
file 是一个文件名,或一个为写入而打开的文件对象。
encoding 是输出编码(默认为 US-ASCII)。
xml_declaration 控制是否应该将 XML 声明添加到文件中。如果不是 US-ASCII 或 UTF-8 或 Unicode,则使用 False 表示从不,True 表示总是,None 仅表示 None(默认为 None)。
default_namespace 设置默认的 XML 名称空间(对于 “xmlns”)。
method 是 “xml”,“html” 或 “text”(默认是 “xml”)。
仅限关键字的 short_empty_elements 参数控制不包含内容的元素的格式。
如果为 True(默认值),则它们作为单个自闭标记发出,否则它们作为一对开始/结束标记发出。
clear() 重置一个元素。清除指定节点元素的所有属性
get(key, default=None) 获取名为 key 的元素属性。返回属性值,如果未找到该属性,则返回默认值
items() 以(名称、值)对序列的形式返回元素属性。属性以任意顺序返回。
keys() 以列表形式返回元素属性名称。名称以任意顺序返回。
set(key, value) 将元素上的属性 key 设置为 value。
et = ET.parse(
"
xmlfile
"
)
root
=
et.getroot()
#
attr = root[0].attrib # 获取到country1节点属性
#
attr.clear() # 清除country1节点中的所有属性,这仅仅是在内存中删除了,xml文件中的内容没有改变
#
et.write("xmlfile") # #将内存中的数据写入xml文件中,此时xml文件中的内容才发生改变
rank1 =
root[0][0]
print
(rank1.get(
"
updated
"
))
#
yes -- get取出对于属性的值
print
(rank1.get(
"
aaa
"
))
#
当元素key不存在时返回None
rank1.set(
"
name
"
,
"
Evan
"
)
#
给节点元素添加属性
et.write(
"
xmlfile
"
)
neighbor1
= root[0][3
]
print
(neighbor1.keys())
#
['direction', 'name']
print
(neighbor1.items())
#
[('direction', 'E'), ('name', 'Austria')]
查找元素方法
findall() 仅查找当前元素的直接子元素中带有指定标签的元素。
find() 查找当前元素带有特定标签的第一个 子级,并返回子级中的元素。
可以用 Element.text 访问元素的文本内容。 Element.get 访问元素的属性
iter() 根据元素名进行深度优先遍历特点节点
<gdppc>141100</gdppc>
test
<neighbor direction=
"
E
"
name=
"
Austria
"
/>
<neighbor direction=
"
W
"
name=
"
Switzerland
"
/>
</country>
<country name=
"
Singapore
"
>
<rank updated=
"
no
"
>5</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor direction=
"
N
"
name=
"
Malaysia
"
/>
</country>
</data>
#
find 和 findall 用法
import
xml.etree.ElementTree as ET
et
= ET.parse(
"
xmlfile
"
)
root
=
et.getroot()
print
(root.find(
"
country
"
))
#
<Element 'country' at 0x000000000120D598>
print
(root.findall(
"
country
"
))
#
[<Element 'country' at 0x000000000120D598>, <Element 'country' at 0x00000000014CCE08>]
print
(root.find(
"
country
"
).get(
"
name
"
))
#
dcs
print
(root.find(
"
country
"
).attrib)
#
{'name': 'dcs'}
for
node
in
root.iter(
'
rank
'
):
print
([node.tag, node.attrib, node.text])
['rank', {'name': 'Evan', 'updated': 'yes'}, '2']
['rank', {'updated': 'no'}, '5']
del 删除节点,删除当前元素索引指定的子级。
remove 删除节点,只能删除当前节点的子节点
<gdppc>141100</gdppc>
test
<neighbor direction=
"
E
"
name=
"
Austria
"
/>
<neighbor direction=
"
W
"
name=
"
Switzerland
"
/>
</country>
<country name=
"
Singapore
"
>
<rank updated=
"
no
"
>5</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor direction=
"
N
"
name=
"
Malaysia
"
/>
</country>
</data>
#
del 和 remove 删除节点操作如下
import
xml.etree.ElementTree as ET
#
del 删除节点
et = ET.parse("xmlfile")
root = et.getroot()
# print(root[0][1].tag) # year
del root[0][1] # 删除第一个country节点下year节点
et.write("xmlfile")
for r in root[0]: # 通过遍历root[0],拿到country下的所有节点元素对象
print(r.tag) # 再通过tag取出country下的所有节点元素对象的节点名称
#
remove 删除节点
tree = ET.parse(
'
xmlfile
'
)
root
=
tree.getroot()
root.remove(root.findall(
"
country
"
))
#
删除了第一个country节点
root.remove(root.findall(
"
country
"
)[1])
#
删除了第二个country节点
tree.write(
"
xmlfile
"
)
#
for i in root.findall('country'): # 找到所用的country节点
#
if i.find('year').text == '2008': # country节点中有year子节点,且year元素的值是‘2008’,就删除此country节点
#
root.remove(i) # 当前节点是root,子节点i是拥有2008值的year节点的country节点
#
tree.write('xmlfile')
修改 XML 文件
使用 Element.text 修改文本字段。
使用 Element.set() 方法添加和修改属性。
使用 Element.append() 添加新的子元素。将元素子元素添加到此元素内部子元素列表的末尾。如果 subelement 不是 Element 则引发 TypeError
修改现有的节点
root
=
et.getroot()
for
node
in
root.iter(
'
year
'
):
node.text
=
'
2012
'
#
将元素名位year的值修改为2012
node.set(
'
Zodiac
'
,
'
monkey
'
)
#
给year元素添加/修改属性,<year Zodiac="monkey">2012</year>
et.write(
'
xmlfile
'
, encoding=
'
UTF-8
'
)
tree = ET.parse(
'
xmlfile
'
)
root
=
tree.getroot()
sub
= ET.fromstring(
'
<myyear/>
'
)
#
准备要添加的元素名
for
item
in
root.iter(
'
country
'
):
#
要加在哪个字段下,这里是将myyear加在country下面
item.append(sub)
for
item
in
root.iter(
'
myyear
'
):
item.text
=
'
永恒,当前
'
#
给myyear元素添加元素值
item.set(
'
末日
'
,
'
到了
'
)
#
给myyear元素添加/修改属性,<year 末日="到了">2012</year>
tree.write(
'
xmlfile
'
, encoding=
'
UTF-8
'
)
root =
tree.getroot()
for
item
in
root.iter(
'
country
'
):
#
要加在哪个字段下,这里是将myyear加在country下面
ET.SubElement(item,
'
myyear
'
)
#
前面是要添加在哪个字段下;后面是要添加的元素名
for
item
in
root.iter(
'
myyear
'
):
item.text
=
'
永恒,当前
'
#
给myyear元素添加元素值
item.set(
'
末日
'
,
'
到了
'
)
#
给myyear元素添加/修改属性,<year 末日="到了">2012</year>
tree.write(
'
xmlfile
'
, encoding=
'
UTF-8
'
)