Python有几种解析XML的方法...
我了解使用SAX解析的基本知识。它具有事件驱动的API,可充当流解析器。
我也了解DOM解析器。它将XML读取到内存中,并将其转换为可以使用Python访问的对象。
一般来说,根据您需要执行的操作,内存限制,性能等,在这两者之间进行选择很容易。
(希望到目前为止我是对的。)
从Python 2.5开始,我们还有ElementTree。与DOM和SAX相比如何?哪个更相似?为什么比以前的解析器更好?
Answers:
ElementTree更加易于使用,因为它(基本上)将XML树表示为列表的结构,而属性则表示为字典。
ElementTree的XML树所需的内存比DOM少得多(因此更快),并且via的解析开销iterparse
与SAX相当。此外,iterparse
返回部分结构,并且您可以在解析过程中通过在处理结构后立即将其丢弃来使内存使用保持恒定。
与成熟的XML库相比,Python 2.5中的ElementTree仅具有很小的功能集,但对于许多应用程序来说已经足够了。如果您需要验证解析器或完整的XPath支持,则可以使用lxml。很长一段时间以来,它一直很不稳定,但是自2.1以来我一直没有遇到任何问题。
ElementTree不同于DOM,在DOM中,节点可以访问其父级和同级。处理实际文档而不是数据存储也很麻烦,因为文本节点不被视为实际节点。在XML代码段中
<a>This is <b>a</b> test</a>
字符串test
将是所谓tail
的element b
。
通常,我建议使用ElementTree作为使用Python进行的所有XML处理的默认设置,并建议使用DOM或SAX作为特定问题的解决方案。
链接。
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的包装耗材也异常类抛出:DOMException,但它不是supperted在minidom命名!
链接。
ElementTree易于使用,并且比XML DOM需要更少的内存。此外,可以使用C实现(xml.etree.cElementTree)。
使用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