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