Python 解析 XML 数据的正确姿势( 二 )

xml.etree.cElementTree 。与DOM相比,ET的速度更快,API使用更直接、方便 。与SAX相比,ET.iterparse函数同样提供了按需解析的功能,不会一次性在内存中读入整个文档 。ET的性能与SAX模块大致相仿,但是它的API更加高层次,用户使用起来更加便捷 。
笔者建议,在使用Python进行XML解析时,首选使用ET模块,除非你有其他特别的需求,可能需要另外的模块来满足 。

解析XML的这几种API并不是Python独创的,Python也是通过借鉴其他语言或者直接从其他语言引入进来的 。例如expat就是一个用C语言开发的、用来解析XML文档的开发库 。而SAX最初是由DavidMegginson采用JAVA语言开发的,DOM可以以一种独立于平台和语言的方式访问和修改一个文档的内容和结构,可以应用于任何编程语言 。
下面,我们以ElementTree模块为例,介绍在Python中如何解析lxml 。
 
利用ElementTree解析XMLPython标准库中,提供了ET的两种实现 。一个是纯Python实现的 xml.etree.ElementTree,另一个是速度更快的C语言实现xml.etree.cElementTree 。请记住始终使用C语言实现,因为它的速度要快很多,而且内存消耗也要少很多 。如果你所使用的Python版本中没有cElementTree所需的加速模块,你可以这样导入模块:
 
  1. try:
  2. import xml.etree.cElementTree as ET
  3. except ImportError:
  4. import xml.etree.ElementTree as ET
如果某个API存在不同的实现,上面是常见的导入方式 。当然,很可能你直接导入第一个模块时,并不会出现问题 。请注意,自Python 3.3之后,就不用采用上面的导入方法,因为 ElemenTree模块会自动优先使用C加速器,如果不存在C实现,则会使用Python实现 。因此,使用Python 3.3+的朋友,只需要importxml.etree.ElementTree即可 。
 
将XML文档解析为树(tree)我们先从基础讲起 。XML是一种结构化、层级化的数据格式,最适合体现XML的数据结构就是树 。ET提供了两个对象:ElementTree将整个XML文档转化为树,Element则代表着树上的单个节点 。对整个XML文档的交互(读取,写入,查找需要的元素),一般是在ElementTree层面进行的 。对单个XML元素及其子元素,则是在Element层面进行的 。下面我们举例介绍主要使用方法 。
我们使用下面的XML文档,作为演示数据:
 
  1. <?xml version="1.0"?>
  2. <doc>
  3. <branch name="codingpy.com" hash="1cdf045c">
  4. text,source
  5. </branch>
  6. <branch name="release01" hash="f200013e">
  7. <sub-branch name="subrelease01">
  8. xml,sgml
  9. </sub-branch>
  10. </branch>
  11. <branch name="invalid">
  12. 【Python 解析 XML 数据的正确姿势】</branch>
  13. </doc>
接下来,我们加载这个文档,并进行解析:
 
  1. >>> import xml.etree.ElementTree as ET
  2. >>> tree = ET.ElementTree(file='doc1.xml')
然后,我们获取根元素(root element):
 
  1. >>> tree.getroot
  2. <Element 'doc' at 0x11eb780>
正如之前所讲的,根元素(root)是一个 Element对象 。我们看看根元素都有哪些属性:
 
  1. >>> root = tree.getroot
  2. >>> root.tag, root.attrib
  3. ('doc', {})
没错,根元素并没有属性 。与其他 Element对象一样,根元素也具备遍历其直接子元素的接口:
 
  1. >>> for child_of_root in root:
  2. ... print child_of_root.tag, child_of_root.attrib
  3. ...
  4. branch {'hash': '1cdf045c', 'name': 'codingpy.com'}
  5. branch {'hash': 'f200013e', 'name': 'release01'}


    推荐阅读