XML解析-ElementTree与SAX和DOM

2024-04-26 13:37:52 发布

您现在位置:Python中文网/ 问答频道 /正文


Tags: python
3条回答

ElementTree的parse()类似于DOM,而iterparse()类似于SAX。在我看来,ElementTree比DOM和SAX更好,因为它提供了更易于使用的API。

ElementTree更易于使用,因为它(基本上)将XML树表示为列表结构,属性表示为字典。

与DOM相比,ElementTree需要的XML树内存要少得多(因此速度更快),通过iterparse的解析开销与SAX相当。另外,iterparse返回部分结构,并且可以在解析期间保持内存使用不变,方法是在处理结构时立即丢弃它们。

ElementTree和Python 2.5一样,与成熟的XML库相比,它只有一个很小的特性集,但对于许多应用程序来说已经足够了。如果您需要一个验证解析器或完整的XPath支持,那么lxml就是一种方法。很长一段时间以来,它一直很不稳定,但从2.1开始我就没有遇到任何问题。

ElementTree与DOM不同,DOM中的节点可以访问其父节点和兄弟节点。处理实际文档而不是数据存储也有点麻烦,因为文本节点不被视为实际节点。在XML片段中

<a>This is <b>a</b> test</a>

字符串test将是元素b的所谓tail

一般来说,我建议使用ElementTree作为所有使用Python处理XML的默认值,使用DOM或SAX作为特定问题的解决方案。

最小的DOM实现:

Link

Python提供了完整的、W3C标准的XML DOM实现(XML.DOM)和最小的一个,XML.DOM.minidom。后者比完整实现更简单、更小。然而,从“解析的角度来看”,它具有标准DOM的所有优点和缺点,即它将所有内容加载到内存中。

考虑一个基本的XML文件:

<?xml version="1.0"?>
<catalog>
    <book isdn="xxx-1">
      <author>A1</author>
      <title>T1</title>
    </book>
    <book isdn="xxx-2">
      <author>A2</author>
      <title>T2</title>
    </book>
</catalog>

使用minidom的一个可能的Python解析器是:

import os
from xml.dom import minidom
from xml.parsers.expat import ExpatError

#-------- Select the XML file: --------#
#Current file name and directory:
curpath = os.path.dirname( os.path.realpath(__file__) )
filename = os.path.join(curpath, "sample.xml")
#print "Filename: %s" % (filename)

#-------- Parse the XML file: --------#
try:
    #Parse the given XML file:
    xmldoc = minidom.parse(filepath)
except ExpatError as e:
    print "[XML] Error (line %d): %d" % (e.lineno, e.code)
    print "[XML] Offset: %d" % (e.offset)
    raise e
except IOError as e:
    print "[IO] I/O Error %d: %s" % (e.errno, e.strerror)
    raise e
else:
    catalog = xmldoc.documentElement
    books = catalog.getElementsByTagName("book")

    for book in books:
        print book.getAttribute('isdn')
        print book.getElementsByTagName('author')[0].firstChild.data
        print book.getElementsByTagName('title')[0].firstChild.data

注意,xml.parsers.expat是expat非验证xml解析器(docs.Python.org/2/library/pyexpat.html)的Python接口。

xml.dom包还提供了异常类dom exception,但它在minidom中不受支持!

ElementTree XML API:

Link

与XML DOM相比,ElementTree更易于使用,而且它需要的内存更少。此外,还提供了一个C实现(xml.etree.celementree)。

使用ElementTree的一个可能的Python解析器是:

import os
from xml.etree import cElementTree  # C implementation of xml.etree.ElementTree
from xml.parsers.expat import ExpatError  # XML formatting errors

#-------- Select the XML file: --------#
#Current file name and directory:
curpath = os.path.dirname( os.path.realpath(__file__) )
filename = os.path.join(curpath, "sample.xml")
#print "Filename: %s" % (filename)

#-------- Parse the XML file: --------#
try:
    #Parse the given XML file:
    tree = cElementTree.parse(filename)
except ExpatError as e:
    print "[XML] Error (line %d): %d" % (e.lineno, e.code)
    print "[XML] Offset: %d" % (e.offset)
    raise e
except IOError as e:
    print "[XML] I/O Error %d: %s" % (e.errno, e.strerror)
    raise e
else:
    catalogue = tree.getroot()

    for book in catalogue:
        print book.attrib.get("isdn")
        print book.find('author').text
        print book.find('title').text

相关问题 更多 >