美文网首页
PYTHON XML解析-SAX解析

PYTHON XML解析-SAX解析

作者: MoonMonsterss | 来源:发表于2018-09-01 22:54 被阅读5次

    1.SAX模块

    SAX是一种基于事件驱动的API,利用SAX解析XML牵扯到两个部分,解析器和事件处理器。其中解析器负责读取XML文档,并向事件处理器发送事件;事件处理器负责做出响应,对处理的XML数据进行处理。
    常用情况:
    1.对大型文件进行处理
    2.只需要文件的部分内容,或者只需要从文件中得到特定信息
    3.想建立自己的对象模型

    2.ContentHandler类常用函数介绍

    2.1 startDocument( self )

    文档启动的时候调用

    2.2 endDocument( self )

    文档解析结束后调用

    2.3 startElement( self, name, attrs )

    遇到XML开始标签时调用,name是标签的名字,attrs是标签的属性值字典,例如<user name='MoonMonster'>,那么便可使用attrs['name']来获取name的值。

    2.4 endElement( self, name )

    遇到XML结束标签时调用,name是结束标签的名称

    2.5 characters( self, content )

    包含在标签中的值,content就是被包含的值

    3.XML示例

    <?xml version="1.0"?>
    <collection shelf="New Arrivals">
        <movie title="Enemy Behind">
            <type>War, Thriller</type>
            <format>DVD</format>
            <year>2003</year>
            <rating>PG</rating>
            <stars>10</stars>
            <description>Talk about a US-Japan war</description>
        </movie>
        <movie title="Transformers">
            <type>Anime, Science Fiction</type>
            <format>DVD</format>
            <year>1989</year>
            <rating>R</rating>
            <stars>8</stars>
            <description>A schientific fiction</description>
        </movie>
    </collection>
    

    4.实例

    如果只是需要从文档中把所有的数据都读取出来,那么直接从character()函数中保存content数据即可,然后在endElement()函数中存储。需要注意的是,这种写法需要将没有直接内容的标签排除掉,例如movie标签,不然会出现没有数据的标签出现数据的情况。还有一点需要注意,如果标签中的数据换行了,会带来很多意料之外的情况,像下面这种。

    <movie title="Enemy Behind">
        <stars>
            10
        </stars>
        <description>Talk about a US-Japan war</description>
    </movie>
    

    from xml import sax
    
    
    class MovieHandler(sax.ContentHandler):
        def __init__(self):
            super().__init__()
            self.content = None
            self.item = {}
            self.items = []
    
        def startDocument(self):
            print('XML文档解析开始...')
    
        def startElement(self, name, attrs):
            if name == 'movie':
                title = attrs['title']
                self.item.update(title=title)
    
        def characters(self, content):
            self.content = content
    
        def endElement(self, name):
            if name == 'movie':
                self.items.append(self.item)
                self.item = {}
            else:
                self.item.update({name: self.content})
    
        def endDocument(self):
            for item in self.items:
                print(item)
                print('*' * 80)
            print('XML文档解析结束...')
    
    
    if __name__ == '__main__':
        handler = MovieHandler()
        parser = sax.make_parser()
        parser.setContentHandler(handler)
        parser.parse('sax.xml')
    

    或者参照网上其他人的写法:
    在这个例子中,使用了self.CurrentData来保存当前标签,但有一个坑的地方是,在endElement函数中,无法获取到像movie这种标签的结束标签。

    from xml import sax
    
    
    class MovieHandler(sax.ContentHandler):
        def __init__(self):
            super().__init__()
            # 初始化数据,并增加一个当前数据
            self.CurrentData = ""
            self.type = ""
            self.format = ""
            self.year = ""
            self.rating = ""
            self.stars = ""
            self.description = ""
    
        # 文档启动的时候调用
        def startDocument(self):
            print('XML开始解析中...')
    
        # 元素开始事件处理
        def startElement(self, name, attrs):
            self.CurrentData = name
            if self.CurrentData == 'movie':
                print('*********movie*********')
                title = attrs['title']
                print('Title:{0}'.format(title))
    
        # 内容事件处理
        def characters(self, content):
            if self.CurrentData == "type":
                self.type = content
            elif self.CurrentData == "format":
                self.format = content
            elif self.CurrentData == "year":
                self.year = content
            elif self.CurrentData == "rating":
                self.rating = content
            elif self.CurrentData == "stars":
                self.stars = content
            elif self.CurrentData == "description":
                self.description = content
    
        # 元素结束事件处理
        def endElement(self, name):
            if self.CurrentData == 'type':
                print('Type:{0}'.format(self.type))
            elif self.CurrentData == 'format':
                print('Format:{0}'.format(self.format))
            elif self.CurrentData == 'year':
                print('Year:{0}'.format(self.year))
            elif self.CurrentData == 'rating':
                print('Rating:{0}'.format(self.rating))
            elif self.CurrentData == 'stars':
                print('Stars:{0}'.format(self.stars))
            elif self.CurrentData == 'description':
                print('Description:{0}'.format(self.description))
            self.CurrentData = ""
    
        # 文档结束的时候调用
        def endDocument(self):
            print('XML文档解析结束!')
    
    
    if __name__ == '__main__':
        handler = MovieHandler()
        parser = sax.make_parser()
        # parser.setFeature(sax.handler.feature_namespaces, 0)
        parser.setContentHandler(handler)
        parser.parse("sax.xml")
    

    5.参考

    https://blog.csdn.net/qq_38377523/article/details/78350548
    https://www.cnblogs.com/chenadong/p/9117156.html
    https://www.cnblogs.com/miniren/p/5091744.html

    相关文章

      网友评论

          本文标题:PYTHON XML解析-SAX解析

          本文链接:https://www.haomeiwen.com/subject/kjkpwftx.html