python 使用sax 解析xml 文件
————转自(12条消息) python 使用sax 解析xml 文件_小牧在一直在学习,在前进的道路上大家一起学习,进步。-CSDN博客
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 不难,可能存在组合数据的时候出现数据重现的问题,这个可以在拼接完数据之后,清空一下数据源,试试看,由于需求不一样,这里就不在写各种需求的组合数据了,大家注意一下数据重复问题即可。
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 不难,可能存在组合数据的时候出现数据重现的问题,这个可以在拼接完数据之后,清空一下数据源,试试看,由于需求不一样,这里就不在写各种需求的组合数据了,大家注意一下数据重复问题即可。

浙公网安备 33010602011771号