python 使用sax 解析xml 文件

这里不是说xml 的所以如果xml 不了解,可以百度大致看下即可,

SAX知识了解

SAX (simple API for XML )  有解析器和事件处理器

解析器负责读取XML文档,并向事件处理器发送事件,如元素开始跟元素结束事件。

而事件处理器则负责对事件作出响应,对传递的XML数据进行处理。

sax的主要方法

1 startDocument() : 文档启动的时候调用。

2 endDocument() : 解析器到达文档结尾时调用。

3 startElement(name, attrs): 遇到XML开始标签时调用,name是标签的名字,attrs是标签的属性值字典。

4 endElement(name) : 遇到XML结束标签时调用。

5 characters :内容处理

6 make_parser : 创建一个解释器对象并返回

7 parser : 解析xml

demo 练习 python的 sax 解析xml

demo1 读取只有标签的xml

创建一个config.xml 的文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<config_content>
    <lib name="a" path="a的路径"/>
    <lib name="b" path="b的路径"/>
    <lib name="c" path="c的路径"/>
</config_content>

代码如下

import xml.sax


class ConfigHandler(xml.sax.ContentHandler):

    def __init__(self):
        self.tag = ""
        self.name = ""
        self.path = ""

    # 启动文档
    def startDocument(self):
        print("******解析配置文件开始******")

    # 开始解析xml
    def startElement(self, name, attributes):
        self.tag = name
        if name == "lib":
            self.name = attributes["name"]
            self.path = attributes["path"]
            print(self.name)
            print(self.path)

    # xml内容事件处理
    def characters(self, content):
        pass

    # 结束解析xml
    def endElement(self, name):
        pass

    # xml结束标签调用
    def endDocument(self):
        print("******配置文件解析结束******")


if __name__ == "__main__":
    # 创建一个 XMLReader
    parser = xml.sax.make_parser()
    # turn off namepsaces
    parser.setFeature(xml.sax.handler.feature_namespaces, 0)
    # 重写 ContextHandler
    Handler = ConfigHandler()
    parser.setContentHandler(Handler)
    # 解析 xml 这里可以写xml 的具体路径,为了简单放在了同一个文件夹里面了
    parser.parse("config.xml")

打印结果如下

由于读取的xml 只有标签这里内容处理和结束的时候并没有做其他的操作,可以出sax 读取xml 的时候是一行一行读取的,这里只有单行所以没有重复的问题,如果我们要使用读取的数据,可以把数据存放到 list 中或者存放到字典中,如下

class ConfigHandler(xml.sax.ContentHandler):
    config_map = {}
    config_name_list = []
    config_path_list = []

    def __init__(self):
        self.tag = ""
        self.name = ""
        self.path = ""

    # 启动文档
    def startDocument(self):
        print("******解析配置文件开始******")

    # 开始解析xml
    def startElement(self, name, attributes):
        self.tag = name
        if name == "lib":
            self.name = attributes["name"]
            self.path = attributes["path"]
            # print(self.name)
            # print(self.path)
            self.config_name_list.append(self.name)
            print(self.config_name_list)
            self.config_path_list.append(self.path)
            print(self.config_path_list)
            self.config_map.update({self.name: self.path})
            print(self.config_map)

    # xml内容事件处理
    def characters(self, content):
        pass

    # 结束解析xml
    def endElement(self, name):
        pass
    # xml结束标签调用
    def endDocument(self):
        print("******配置文件解析结束******")


if __name__ == "__main__":
    # 创建一个 XMLReader
    parser = xml.sax.make_parser()
    # turn off namepsaces
    parser.setFeature(xml.sax.handler.feature_namespaces, 0)
    # 重写 ContextHandler
    Handler = ConfigHandler()
    parser.setContentHandler(Handler)
    # 解析 xml 这里可以写xml 的具体路径,为了简单放在了同一个文件夹里面了
    parser.parse("config.xml")

打印结果

demo2 读取同标签不同内容的xml

xml内容如下

<?xml version="1.0" encoding="UTF-8"?>
<config_content>
    <type class="3年级">
        <lib name="体育">优秀</lib>
        <lib name="语文">一般</lib>
        <lib name="数学">优秀</lib>
    </type>
    <type class="5年级">
        <lib name="体育">一般</lib>
        <lib name="语文">优秀</lib>
        <lib name="数学">良好</lib>
    </type>
</config_content>

python 代码如下

import xml.sax


class ConfigHandler(xml.sax.ContentHandler):

    def __init__(self):
        self.tag = ""
        self.name = ""
        self.label = ""
        self.content = ""

    # 启动文档
    def startDocument(self):
        print("******解析配置文件开始******")

    # 开始解析xml
    def startElement(self, name, attributes):
        self.tag = name
        if name == "type":
            self.name = attributes["class"]
            print(self.name)
        if name == "lib":
            self.label = attributes["name"]
            print(self.label)

    # xml内容事件处理
    def characters(self, content):
        self.content = content

    # 结束解析xml
    def endElement(self, name):
        if name == "lib":
            print(self.content)

    # xml结束标签调用
    def endDocument(self):
        print("******配置文件解析结束******")


if __name__ == "__main__":
    # 创建一个 XMLReader
    parser = xml.sax.make_parser()
    # turn off namepsaces
    parser.setFeature(xml.sax.handler.feature_namespaces, 0)
    # 重写 ContextHandler
    Handler = ConfigHandler()
    parser.setContentHandler(Handler)
    # 解析 xml 这里可以写xml 的具体路径,为了简单放在了同一个文件夹里面了
    parser.parse("config.xml")

打印结果如下


demo3 读取相同标签多个标题的xml

xml 内容如下

<?xml version="1.0" encoding="UTF-8"?>
<config_content>
    <school name="第六中学">
        <type class="2年级">
            <Language>优秀</Language>
            <Math>一般</Math>
            <English>优秀</English>
        </type>
        <type class="5年级">
            <Language>优秀</Language>
            <Math>一般</Math>
            <English>优秀</English>
        </type>
    </school>
      <school name="第九中学">
        <type class="1年级">
            <Language>优秀</Language>
            <Math>一般</Math>
            <English>优秀</English>
        </type>
        <type class="3年级">
            <Language>优秀</Language>
            <Math>一般</Math>
            <English>优秀</English>
        </type>
    </school>
</config_content>

python 代码如下

import xml.sax


class ConfigHandler(xml.sax.ContentHandler):

    def __init__(self):
        self.tag = ""
        self.name = ""
        self.label = ""
        self.content = ""

    # 启动文档
    def startDocument(self):
        print("******解析配置文件开始******")

    # 开始解析xml
    def startElement(self, name, attributes):
        self.tag = name
        if name == "school":
            self.name = attributes["name"]
            print(self.name)
        if name == "type":
            self.label = attributes["class"]
            print(self.label)

    # xml内容事件处理
    def characters(self, content):
        self.content = content

    # 结束解析xml
    def endElement(self, name):
        if name == "Language":
            print(self.content)
        elif name == "Math":
            print(self.content)
        elif name == "English":
            print(self.content)

    # xml结束标签调用
    def endDocument(self):
        print("******配置文件解析结束******")


if __name__ == "__main__":
    # 创建一个 XMLReader
    parser = xml.sax.make_parser()
    # turn off namepsaces
    parser.setFeature(xml.sax.handler.feature_namespaces, 0)
    # 重写 ContextHandler
    Handler = ConfigHandler()
    parser.setContentHandler(Handler)
    # 解析 xml 这里可以写xml 的具体路径,为了简单放在了同一个文件夹里面了
    parser.parse("config.xml")

打印结果如下:

******解析配置文件开始******
第六中学
2年级
优秀
一般
优秀
5年级
优秀
一般
优秀
第九中学
1年级
优秀
一般
优秀
3年级
优秀
一般
优秀
******配置文件解析结束******

最后总结,python 使用sax 读取xml 不难,可能存在组合数据的时候出现数据重现的问题,这个可以在拼接完数据之后,清空一下数据源,试试看,由于需求不一样,这里就不在写各种需求的组合数据了,大家注意一下数据重复问题即可。

 

 

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值