python 使用sax 解析xml 文件_python sax解析xml_胡小牧的博客-程序员秘密

技术标签: Python  

这里不是说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 不难,可能存在组合数据的时候出现数据重现的问题,这个可以在拼接完数据之后,清空一下数据源,试试看,由于需求不一样,这里就不在写各种需求的组合数据了,大家注意一下数据重复问题即可。

 

 

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_33210042/article/details/117706970

智能推荐

iOS - OC NSTimer 定时器_weixin_34124651的博客-程序员秘密

前言 @interface NSTimer : NSObject @interface CADisplayLink : NSObject作用在指定的时间执行指定的任务。每隔一段时间执行指定的任务。1、定时器的创建1.1 NSTimer 定时器当定时器创建完(不用 scheduled 的,添加到 runlo...

arm64汇编篇-11循环while、for_while循环和for循环汇编_Clement_Gu的博客-程序员秘密

while循环创建工程-&amp;gt;main函数页面写入以下代码:void func(){ int nSum = 0; int i = 0; while (i &amp;lt;= 100){ nSum = nSum + 1; i++; }}2.真机编译将得出的mach-O文件放入ida64中解析获得以下结果: 注:ida的操...

python面向对象设计的三要素_Python面向对象设计和面向对象编程解析_璟落的博客-程序员秘密

我们都知道Python是一门灵活度很高的语言,它可以面向过程,面向对象,那我们今天说说Python中的面向对象设计和面向对象编程的区别面向对象设计和面向对象编程都提到了“面向对象”, 那么首先我们要搞清楚什么是对象对象:我们可以简单的理解为我们见到的每个实际存在的事物就是一个对象,如果一个人,一座房子,一只小猫等。那么我们想想,我们怎么面向对象,那就是以对象为中心,去描述这个对象,这个对象有什么特...

IBM面试题试解(关于50条狗、50个人、病狗)_achellies的博客-程序员秘密

题目:村子里有50个人,每人有一条狗,在这50条狗中有病狗(这种病不传染),于是人们要找出病狗。 每个人可以观察其他49条狗,以判断他们是否生病,(如果有病一定能看出来),只有自己的狗不能看,观察后得到的结果不得交流,也不能通知病狗的主人。主人一旦推算出自己家的狗是病狗就是枪毙自己的狗(发现后必须在一天内枪毙),而且每个人只有权利枪毙自己的狗,没有权利打死其他人的狗。第一天大家全看完了,但枪没

【Vue】 scrollTop赋值一直为0_vue里面的scrolltop一直为0_android_zier的博客-程序员秘密

Vue项目中,给scrollTop赋值一直0,解决方案总结如下:mounted中:window设置scroll滚动事件window.addEventListener('scroll', () =&gt; { this.scrollGroupSetting()}, false)destroyed中:移除scroll滚动事件window.removeEventListener('scroll', this.scrollGroupSetting(true), false)获取scro

[SAP PI]ECC系统接收财务凭证IDoc的配置步骤(总账 应收 应付)_sap pi idoc_SAP剑客的博客-程序员秘密

1.       业务场景外围系统,通过IDoc,在SAP系统中创建财务凭证,包括总账,应收和应付.功能IDoc增强财务总账接口ACC_GL_POSTING. ACC_GL_POSTING01ACBAPI01 EXIT_SAPLACC4_001财务应收接口ACC_BILLING. ACC_BILLING02同上财务应付

随便推点

Leaflet API 翻译(二)_lineutil.simplify_zhouschina的博客-程序员秘密

L.Point显示以像素为单位的点的x,y坐标。所以接受点对象的leaflet方法和选项都也接受他们简单数组的形式。Constructor(函数构造器)L.Point():用给定点的x和y坐标来创建点对象。如果round设置为true,则将x和y的值转换为圆中。?Properties(属性)x:x坐标。y:y坐标。Method

嵌入式Linux引导过程之1.4——Xloader的ddr_init_xloader.zip_毛毛虫的爹的博客-程序员秘密

这里我们来看XLOADER_ENTRY中调用的第二个标号ddr_init处的代码,这部分代码的作用是对外部内存SDRAM进行初始化,在我 spearplus开发板中,使用的是DDR SDRAM。在调用ddr_init之前,外部内存是不能用的,因为外部内存的时钟以及控制寄存器都还没有初始化,因此此时只有芯片内部的SRAM以及在 sys_init的时候已经初始化了的Serial Flash、UART

sklearn构建stacking模型进行堆叠多模型分层级回归分析_sklearn stacking_Data+Science+Insight的博客-程序员秘密

sklearn构建stacking模型进行堆叠多模型分层级回归分析Stacking 就是当用初始训练数据学习出若干个基学习器后,将这几个学习器的预测结果作为新的训练集,来学习一个新的学习器。Stacking 的基础层通常包括不同的学习算法,因此stacking ensemble往往是异构的。stacking的步骤:假设有1000个样本,70%的样本作为训练集,30%的样本作为测试集。STEP1:在训练集上采用算法A、B、C等训练出一系列基学习器。STEP2:用这些基学习器的输出结果.

杭电acm刷题顺序Java_HDU、ZOJ、POJ刷题(难易)顺序_迷路的穿山甲的博客-程序员秘密

简单题AC总数大于500,且AC百分比大于60%2304、 1673、 5630、 5232、 4450、 2560、 4633、 5949、 1564、 6322、 1576、 2042、 1220、 1721、 2500、 2317、 1992、 4572、 5591、 5982、 1849、 2501、 ...

思科发布全新CCIE体系!_阿南君的博客-程序员秘密

就在今天凌晨,思科发布了最新CCIE认证体系!2020年2月24日开始启用!小编带大家第一时间了解此次认证体系的变化!※ R&amp;S CCIE退出历史舞台替代CCIE R&amp;S的是CCIE Enterprise Infrastructure(企业基础架构)全新大纲不仅要考DNA还要考SDWAN这两项技术正是YESLAB这两年一直重...

PyCharm安装教程(配置两个解释器)_pycharm解释器怎么安装_ThetaQing的博客-程序员秘密

有的时候我们会需要访问其他文件夹下的函数,简单地说就是需要访问其他自定义的包,如果项目较大的话,在每个文件下添加import syssys.path.append("包的上一级绝对路径")就会显得很麻烦,而且也不适合移植,所以,我们可以选用在PyCharm中直接将这个路径作为环境变量就省事多了。1、在PyCharm中选择那个文件夹...