python 使用sax 解析xml 文件

我不是女神ヾ 2022-10-05 10:46 389阅读 0赞

这里不是说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 的文件内容如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <config_content>
  3. <lib name="a" path="a的路径"/>
  4. <lib name="b" path="b的路径"/>
  5. <lib name="c" path="c的路径"/>
  6. </config_content>

代码如下

  1. import xml.sax
  2. class ConfigHandler(xml.sax.ContentHandler):
  3. def __init__(self):
  4. self.tag = ""
  5. self.name = ""
  6. self.path = ""
  7. # 启动文档
  8. def startDocument(self):
  9. print("******解析配置文件开始******")
  10. # 开始解析xml
  11. def startElement(self, name, attributes):
  12. self.tag = name
  13. if name == "lib":
  14. self.name = attributes["name"]
  15. self.path = attributes["path"]
  16. print(self.name)
  17. print(self.path)
  18. # xml内容事件处理
  19. def characters(self, content):
  20. pass
  21. # 结束解析xml
  22. def endElement(self, name):
  23. pass
  24. # xml结束标签调用
  25. def endDocument(self):
  26. print("******配置文件解析结束******")
  27. if __name__ == "__main__":
  28. # 创建一个 XMLReader
  29. parser = xml.sax.make_parser()
  30. # turn off namepsaces
  31. parser.setFeature(xml.sax.handler.feature_namespaces, 0)
  32. # 重写 ContextHandler
  33. Handler = ConfigHandler()
  34. parser.setContentHandler(Handler)
  35. # 解析 xml 这里可以写xml 的具体路径,为了简单放在了同一个文件夹里面了
  36. parser.parse("config.xml")

打印结果如下

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzMjEwMDQy_size_16_color_FFFFFF_t_70

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

  1. class ConfigHandler(xml.sax.ContentHandler):
  2. config_map = {}
  3. config_name_list = []
  4. config_path_list = []
  5. def __init__(self):
  6. self.tag = ""
  7. self.name = ""
  8. self.path = ""
  9. # 启动文档
  10. def startDocument(self):
  11. print("******解析配置文件开始******")
  12. # 开始解析xml
  13. def startElement(self, name, attributes):
  14. self.tag = name
  15. if name == "lib":
  16. self.name = attributes["name"]
  17. self.path = attributes["path"]
  18. # print(self.name)
  19. # print(self.path)
  20. self.config_name_list.append(self.name)
  21. print(self.config_name_list)
  22. self.config_path_list.append(self.path)
  23. print(self.config_path_list)
  24. self.config_map.update({self.name: self.path})
  25. print(self.config_map)
  26. # xml内容事件处理
  27. def characters(self, content):
  28. pass
  29. # 结束解析xml
  30. def endElement(self, name):
  31. pass
  32. # xml结束标签调用
  33. def endDocument(self):
  34. print("******配置文件解析结束******")
  35. if __name__ == "__main__":
  36. # 创建一个 XMLReader
  37. parser = xml.sax.make_parser()
  38. # turn off namepsaces
  39. parser.setFeature(xml.sax.handler.feature_namespaces, 0)
  40. # 重写 ContextHandler
  41. Handler = ConfigHandler()
  42. parser.setContentHandler(Handler)
  43. # 解析 xml 这里可以写xml 的具体路径,为了简单放在了同一个文件夹里面了
  44. parser.parse("config.xml")

打印结果

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzMjEwMDQy_size_16_color_FFFFFF_t_70 1

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

xml内容如下

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <config_content>
  3. <type class="3年级">
  4. <lib name="体育">优秀</lib>
  5. <lib name="语文">一般</lib>
  6. <lib name="数学">优秀</lib>
  7. </type>
  8. <type class="5年级">
  9. <lib name="体育">一般</lib>
  10. <lib name="语文">优秀</lib>
  11. <lib name="数学">良好</lib>
  12. </type>
  13. </config_content>

python 代码如下

  1. import xml.sax
  2. class ConfigHandler(xml.sax.ContentHandler):
  3. def __init__(self):
  4. self.tag = ""
  5. self.name = ""
  6. self.label = ""
  7. self.content = ""
  8. # 启动文档
  9. def startDocument(self):
  10. print("******解析配置文件开始******")
  11. # 开始解析xml
  12. def startElement(self, name, attributes):
  13. self.tag = name
  14. if name == "type":
  15. self.name = attributes["class"]
  16. print(self.name)
  17. if name == "lib":
  18. self.label = attributes["name"]
  19. print(self.label)
  20. # xml内容事件处理
  21. def characters(self, content):
  22. self.content = content
  23. # 结束解析xml
  24. def endElement(self, name):
  25. if name == "lib":
  26. print(self.content)
  27. # xml结束标签调用
  28. def endDocument(self):
  29. print("******配置文件解析结束******")
  30. if __name__ == "__main__":
  31. # 创建一个 XMLReader
  32. parser = xml.sax.make_parser()
  33. # turn off namepsaces
  34. parser.setFeature(xml.sax.handler.feature_namespaces, 0)
  35. # 重写 ContextHandler
  36. Handler = ConfigHandler()
  37. parser.setContentHandler(Handler)
  38. # 解析 xml 这里可以写xml 的具体路径,为了简单放在了同一个文件夹里面了
  39. parser.parse("config.xml")

打印结果如下

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzMjEwMDQy_size_16_color_FFFFFF_t_70 2

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

xml 内容如下

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <config_content>
  3. <school name="第六中学">
  4. <type class="2年级">
  5. <Language>优秀</Language>
  6. <Math>一般</Math>
  7. <English>优秀</English>
  8. </type>
  9. <type class="5年级">
  10. <Language>优秀</Language>
  11. <Math>一般</Math>
  12. <English>优秀</English>
  13. </type>
  14. </school>
  15. <school name="第九中学">
  16. <type class="1年级">
  17. <Language>优秀</Language>
  18. <Math>一般</Math>
  19. <English>优秀</English>
  20. </type>
  21. <type class="3年级">
  22. <Language>优秀</Language>
  23. <Math>一般</Math>
  24. <English>优秀</English>
  25. </type>
  26. </school>
  27. </config_content>

python 代码如下

  1. import xml.sax
  2. class ConfigHandler(xml.sax.ContentHandler):
  3. def __init__(self):
  4. self.tag = ""
  5. self.name = ""
  6. self.label = ""
  7. self.content = ""
  8. # 启动文档
  9. def startDocument(self):
  10. print("******解析配置文件开始******")
  11. # 开始解析xml
  12. def startElement(self, name, attributes):
  13. self.tag = name
  14. if name == "school":
  15. self.name = attributes["name"]
  16. print(self.name)
  17. if name == "type":
  18. self.label = attributes["class"]
  19. print(self.label)
  20. # xml内容事件处理
  21. def characters(self, content):
  22. self.content = content
  23. # 结束解析xml
  24. def endElement(self, name):
  25. if name == "Language":
  26. print(self.content)
  27. elif name == "Math":
  28. print(self.content)
  29. elif name == "English":
  30. print(self.content)
  31. # xml结束标签调用
  32. def endDocument(self):
  33. print("******配置文件解析结束******")
  34. if __name__ == "__main__":
  35. # 创建一个 XMLReader
  36. parser = xml.sax.make_parser()
  37. # turn off namepsaces
  38. parser.setFeature(xml.sax.handler.feature_namespaces, 0)
  39. # 重写 ContextHandler
  40. Handler = ConfigHandler()
  41. parser.setContentHandler(Handler)
  42. # 解析 xml 这里可以写xml 的具体路径,为了简单放在了同一个文件夹里面了
  43. parser.parse("config.xml")

打印结果如下:

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

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

发表评论

表情:
评论列表 (有 0 条评论,389人围观)

还没有评论,来说两句吧...

相关阅读

    相关 SAX解析XML

    SAX(Simple API for XML)也是一种解析 XML 文件的方法,它虽然不是官方标准,但它是 XML 的事实标准,大部分 XML 解析器都支持它。 SAX 与

    相关 Java——SAX解析XML文件

    SAX适用于只读取XML文件内容的情况,因为SAX是一种边读边解析的模式,所以不需要直接将XML文件直接塞入内存,读取速度也更快,但是只能读。 SAX解析主要有两个部分:①

    相关 PythonSAX解析XML

    SAX 是一种基于事件驱动的API。 利用 SAX 解析 XML 文档牵涉到两个部分: 解析器和事件处理器。 解析器负责读取 XML 文档,并向事件处理器发送事件,如元

    相关 SAX解析XML

    SAX(Simple API for XML)也是一种解析 XML 文件的方法,它虽然不是官方标准,但它是 XML 的事实标准,大部分 XML 解析器都支持它。 SAX ...