XMLparsing – ElementTree与SAX和DOM

Python有几种方法来parsingXML …

我理解用SAXparsing的基础知识。 它作为一个streamparsing器,具有事件驱动的API。

我也了解DOMparsing器。 它将XML读入内存,并将其转换为可以用Python访问的对象。

一般来说,根据你需要做什么,记忆的限制,性能等,在2之间进行select是很容易的。

(希望我到目前为止是正确的)。

从Python 2.5开始,我们也有ElementTree 。 这与DOM和SAX相比如何? 哪个更类似? 为什么比以前的parsing器更好?

ElementTree更容易使用,因为它表示一个XML树(基本上)作为列表的结构,属性表示为字典。

ElementTree比DOM更需要XML树的内存(因此速度更快),并且通过iterparse的parsing开销与SAX相当。 此外, iterparse返回部分结构,并且可以在parsing过程中保持内存使用不变,只要处理它们即可丢弃结构。

与Python 2.5相比,ElementTree与完整的XML库相比只有一小部分function,但对于许多应用程序来说,它已经足够了。 如果您需要validationparsing器或完整的XPath支持,则需要使用lxml。 很长时间以来,它一直很不稳定,但自从2.1以来,我一直没有遇到任何问题。

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

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

stringtest将是所谓的元素b tail

一般来说,我推荐ElementTree作为Python的所有XML处理的默认值,DOM或SAX作为特定问题的解决scheme。

最小的DOM实现:

链接: http : //docs.python.org/2/library/xml.dom.minidom.html#module-xml.dom.minidom

Python提供了XML DOM( xml.dom )的完整W3C标准实现,以及最小的XML.dom.minidom 。 后者比完整的实现更简单和更小。 但是,从“parsing视angular”来看,它具有标准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的可能的Pythonparsing器是:

 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非validationXMLparsing器(docs.python.org/2/library/pyexpat.html)的Python接口。

xml.dom包也提供exception类DOMException ,但它不在minidom中提供

ElementTree XML API:

链接: http : //docs.python.org/2/library/xml.etree.elementtree.html

ElementTree使用起来要容易得多,它比XML DOM需要更less的内存。 此外,可以使用C实现( xml.etree.cElementTree )。

一个使用ElementTree的可能的Pythonparsing器是:

 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 

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

ElementTree有更多pythonic API。 现在它也在标准库中,所以使用它可以减less依赖性。

我实际上更喜欢lxml,因为它具有像ElementTree这样的API,但也有很好的附加function并且性能良好。