Python解析xml

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python解析xml相关的知识,希望对你有一定的参考价值。

XML 被设计用来传输和存储数据。

HTML 被设计用来显示数据。

  XML(eXtensible Markup Language)指可扩展标记语言,被设计用来传输和存储数据,已经日趋成为当前许多新生技术的核心,在不同的领域都有着不同的应用。它是web发展到一定阶段的必然产物,既具有SGML的核心特征,又有着HTML的简单特性,还具有明确和结构良好等许多新的特性。
        python解析XML常见的有三种方法:一是xml.dom.*模块,它是W3C DOM API的实现,若需要处理DOM API则该模块很适合,注意xml.dom包里面有许多模块,须区分它们间的不同;二是xml.sax.*模块,它是SAX API的实现,这个模块牺牲了便捷性来换取速度和内存占用,SAX是一个基于事件的API,这就意味着它可以“在空中”处理庞大数量的的文档,不用完全加载进内存;三是xml.etree.ElementTree模块(简称 ET),它提供了轻量级的Python式的API,相对于DOM来说ET 快了很多,而且有很多令人愉悦的API可以使用,相对于SAX来说ET的ET.iterparse也提供了 “在空中” 的处理方式,没有必要加载整个文档到内存,ET的性能的平均值和SAX差不多,但是API的效率更高一点而且使用起来很方便。

Python解析xml的三种方式为:Element tree、DOM、SAX

 

Element tree:

Element类型是一种灵活的容器对象,用于在内存中存储层次数据结构。可以说是list和dictionary的交叉,它生来就是为了处理XML,它在Python标准库中有两种实现:一种是纯Python实现的,如xml.etree.ElementTree,另一种是速度快一点的xml.etree.cElementTree。注意:尽量使用C语言实现的那种,因为它速度更快,而且消耗的内存更少。

Element tree会将xml文件解析为元素树。

每个element都有一系列相关属性:

  • 标签,用于标识该元素表示哪种数据(即元素类型)
  • 一些属性,存储在Python dictionary中
  • 一个文本字符串
  • 一个可选的尾字符串
  • 一些孩子elements,存储在Python sequence中

abc.xml文件如下

<?xml version="1.0"?>
<!--主节点为data  孩子节点为country,也就是二级tag-->
<data>
  <country name="Singapore" area="Asia">
    <rank>4</rank>
    <year>2011</year>
    <gdppc>59900</gdppc>
    <neighbor name="Malaysia" direction="N"/>
  </country>
  <country name="Panama" area="NA">
    <rank>68</rank>
    <year>2011</year>
    <gdppc>13600</gdppc>
    <neighbor name="Costa Rica" direction="W"/>
    <neighbor name="Colombia" direction="E"/>
  </country>
</data>

使用Element tree解析的python代码如下:

import xml.etree.ElementTree as ET  #在这里还可以使用c实现的  速度更快,写法如下
‘‘‘try:
  import xml.etree.ElementTree as ET
except ImportError:
  import xml.etree.cElementTree as ET‘‘‘
import sys try: tree = ET.parse(abc.xml) #打开xml文件生成解析对象 # root = ET.fromstring(‘xml字符串‘) #解析xml字符串时,解析函数生成元素树 root = tree.getroot() #得到根节点 except Exception as e: print(‘parse object error) sys.exit(1) print(root.tag, "---", root.attrib) #root.tag值为data,而列属性attrib不存在值 for child in root: #遍历子节点 print(child.tag, "---", child.attrib) #child节点的tag属性,子节点的列属性存在值 print("*"*10) print(year:+root[0][1].text) #root[0]为第一个子节点:第一个country print(root[0].tag, root[0][1].text) # root[0]的意思是第一个子节点的tag属性, 所以root[0][1].text意思就是:访问文本内容得到第一个子节点的第二个标签数据,这种方法是通过根节点来得到的,还可以通过根节点的遍历查找拿到。 print("*"*10) for cons in root.findall(country): #从根节点开始遍历寻找country节点 rank = cons.find(rank).text #想拿到子节点中rank标签对嵌入的值 neighbor = cons.find(neighbor).get(name) # 查找country中neighbor这个tag ,然后再拿到列中name属性 name = cons.get(name) #子节点的get方法直接拿到列中想要的属性 area = cons.get(area) #同上 print(country:+name+\\narea:+area+\\nranking:+rank+\\nneighbor:+neighbor+\\n)

结果如下:

data --- {}
country --- {name: Singapore, area: Asia}
country --- {name: Panama, area: NA}
**********
year:2011
country 2011
**********
country:Singapore
area:Asia
ranking:4
neighbor:Malaysia

country:Panama
area:NA
ranking:68
neighbor:Costa Rica

同时Element还可以迭代遍历子树:

for country in root.iter(country):
    print(country.attrib)
    #同时迭代出的字树也可以拿到列属性,
  #name = country.get(‘name‘)
  #
不仅一个列可以拿到,相同子节点所有文本内容都可拿到....
  #rank = country.find(‘rank‘).text
for neighbor in root.iter(neighbor):
    print(neighbor.attrib)

结果:

{name: Singapore, area: Asia}
{name: Panama, area: NA}


{name: Malaysia, direction: N}
{name: Costa Rica, direction: W}
{name: Colombia, direction: E}

 ElementTree.write() 提供了修改xml文件的方法

#此处剔除排名大于50的国家
for country in root.iter(country):
    rank = int(country.find(rank).text)
    if rank > 50:
        root.remove(country)
tree.write(output.xml)

结果另一个country字树被剔除,output.xml如下:

技术分享

如何修改子节点中标签的属性?

修改rank排名。每个国家前进一名

#使每个国家排名前进一名
for rank in root.iter(rank):
    # uprank = int()
    print(rank.text)
    uprank = int(rank.text) - 1
    rank.text = str(uprank)
tree.write(out.xml)

结果

技术分享

还可以为标签添加属性

for rank in root.iter(rank):
    # uprank = int()
    print(rank.text)
    uprank = int(rank.text) - 1
    rank.text = str(uprank)
    rank.set(after_modify, success)  #使用set方法即可修改
tree.write(out.xml)

out.xml

<data>
  <country area="Asia" name="Singapore">
    <rank after_modify="success">3</rank>
    <year>2011</year>
    <gdppc>59900</gdppc>
    <neighbor direction="N" name="Malaysia" />
  </country>
  <country area="NA" name="Panama">
    <rank after_modify="success">67</rank>
    <year>2011</year>
    <gdppc>13600</gdppc>
    <neighbor direction="W" name="Costa Rica" />
    <neighbor direction="E" name="Colombia" />
  </country>
</data>

细则参见官方文档:xml.etree.ElementTree

DOM和SAX可以参考其他的博客

 










以上是关于Python解析xml的主要内容,如果未能解决你的问题,请参考以下文章

从流输入中解析没有根元素的 XML 片段列表

无法解析片段中的 findViewById [重复]

jsoup解析xml某片段的问题

Android 逆向使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 创建反汇编解析器实例对象 | 设置汇编解析器显示细节 )(代码片段

如何在 python 代码中解析多个 xml 文件?

为 Blogger 上的博客格式化代码片段 [关闭]