Python SAX 解析XML文件

摘要

SAX是基于事件驱动的。在处理过程中,它将XML文档的处理转化为一系列事件的处理,通过事件处理器处理XML文档。它的速度很快,而且占用的内存很小,适用于一些比较大的XML文件。

SAX的简介:

SAX是基于事件驱动的。在处理过程中,它将XML文档的处理转化为一系列事件的处理,通过事件处理器处理XML文档。它的速度很快,而且占用的内存很小,适用于一些比较大的XML文件。

这里我们使用 SAX 解析以下内容的 XML 文件,打印输出所有 2008 年入学的学生的不
及格记录。注:学号(sno)的头四位表示了学生的入学年份。


先上处理代码:

# -*- coding: utf-8 -*-
#XML处理  
#SAX处理XML的方式和Java中的SAX解析器一样,从ContentHandler方法中继承,并处理startDocument、endDocument等信息  
from xml.sax import *  
#必须从xml.sax包中导入所有方法和变量
class MarkDecodeHandler(ContentHandler):  
#与Java的SAXParser基本一致,处理方法一样  
    marks=None#marks是列表存储一个一个的mark的   
    temp=""
    mystr=""
    currenttag=None  
    mark=None  
    #注意Python的特殊格式,必须有self作为第一个参数  
    def startDocument(self):
        print "start xml document"  
          
    def endDocument(self):  
        print "end xml document"
        
    #name=当前处理的标签名,attrs以dict的格式存放标签的所有属性  
    def startElement(self,name,attrs):  
        if name=="marks":  
            self.marks=[]  
        elif name=="student":  
            self.mark={"name":attrs['name']}
            self.mark.update({"sno":attrs['sno']})
        elif name=="mark":<span style="font-family: Arial, Helvetica, sans-serif;">#如果标签名为mark,则记录此时的course名(因为course有很多个,这次使用mystr能够标识出course和其对应的分数)</span>
            self.mystr=attrs['course']
            self.mark.update({self.mystr:''})
        self.currenttag=name
      
    def endElement(self,name):  
        if name=="student":  
            self.marks.append(self.mark)
        elif name=="mark":#如果标签名为mark,插入这个标签对应的分数,比如{"math":80}
            self.mark.update({self.mystr:self.temp.strip()})
            self.temp=""
        self.currenttag=None  
    #content表示正在处理中的数据    
    def characters(self,content):  
        self.temp+=content  


if __name__ == '__main__':
    #调用make_parser方法创建一个SAX解析器  
    # '''  
    print u"===============Python SAX方式解析XML文档==================="  
    parser=make_parser()  
    handler=MarkDecodeHandler()  
    parser.setContentHandler(handler)  
    data=""  
    with open("Student.xml") as file:  
        data=file.read().strip()  
    import StringIO  
    #StringIO模块用于将字符串转换成流数据,类似于Java的ByteArrayOutputStream和ByteArrayInputStream  
    parser.parse(StringIO.StringIO(data))  
      
    for item in handler.marks:#marks是列表  
        for i in item.items():  
            key,value=i
            if key != 'name' and key != 'sno' and item['sno'][:4] == '2008' and int(value) < int(60):
                print item['sno'],'=',item['name'],'=',key,'=>',value
    #'''

给出相应的XML文件:

<?xml version="1.0" encoding="utf-8"?>
<marks>
	<student name="张三" sno="200818237">
		<mark course="物理">80</mark>
		<mark course="化学">85</mark>
		<mark course="生物">90</mark>
		<mark course="文学">50</mark>
		<mark course="代数">70</mark>
	</student>
	<student name="李四" sno="200918250">
		<mark course="物理">30</mark>
		<mark course="化学">60</mark>
		<mark course="生物">90</mark>
		<mark course="代数">45</mark>
	</student>
	<student name="王二麻子" sno="200818180">
		<mark course="物理">90</mark>
		<mark course="化学">85</mark>
		<mark course="生物">90</mark>
		<mark course="文学">35</mark>
		<mark course="代数">70</mark>
	</student>
</marks>

解析结果:

>>> 
===============Python SAX方式解析XML文档===================
start xml document
end xml document
200818237 = 张三 = 文学 => 50
200818180 = 王二麻子 = 文学 => 35
>>>


IT家园
IT家园

网友最新评论 (0)