python之XML解析
XML 指可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。
XML 被设计用来传输和存储数据。XML适用于跟踪中小型数据而无需基于SQL的主干。
Python 对 XML 的解析常见的 XML 编程接口有 DOM 和 SAX,这两种接口处理 XML 文件的方式不同,使用场景也不同。
Python有三种方法解析XML,分别是SAX、DOM和ElementTree:
SAX:Python 标准库包含 SAX 解析器,SAX 用事件驱动模型,通过在解析 XML 的过程中触发一个个的事件并调用用户定义的回调函数来处理 XML 文件。
DOM:将 XML 数据在内存中解析成一个树,通过对树的操作来操作 XML。
ElementTree:ElementTree(元素树)就像一个轻量级的DOM,具有方便友好的API。代码可用性好,速度快,消耗内存少。
因DOM需要将XML数据映射到内存中的树,会比较慢和消耗内存,而SAX流式读取XML文件,比较快,占用内存少,但需要用户实现回调函数(handler)。
本章节使用到的 XML 实例文件movies.xml内容如下:
<collection shelf="新品推荐"><movie title="重返二十岁"><type>喜剧,亲情,爱情,奇幻</type><format>DVD</format><year>2014</year><rating>PG</rating><stars>8</stars><description>影片讲述了一位七旬老太太不可思议变身为妙龄女子后,以新身份回到日常生活,引发的一系列啼笑皆非的奇幻故事</description></movie><movie title="流浪地球"><type>科幻、灾难、冒险、动作</type><format>DVD</format><year>2019</year><rating>R</rating><stars>10</stars><description>讲述了太阳即将毁灭,已经不适合人类生存,而面对绝境,人类将开启“流浪地球”计划</description></movie><movie title="恶棍天使"><type>喜剧,爱情</type><format>DVD</format><year>2015</year><rating>PG</rating><stars>10</stars><description>讲述了高智商低情商女学霸查小刀遇到专职替人讨债的恶棍莫非里,俩人在神医折耳根的介绍下互相“治疗”发生的一系列故事</description></movie><movie title="战狼"><type>动作,战争,军事</type><format>VHS</format><year>2015</year><rating>PG</rating><stars>10</stars><description>讲述的是小人物成长为拯救国家和民族命运的孤胆英雄的传奇故事</description></movie></collection> 使用SAX API解析XMLSAX 是一种基于事件驱动的API。利用 SAX 解析 XML 文档牵涉到两个部分,解析器和事件处理器。解析器负责读取 XML 文档,并向事件处理器发送事件,如元素开始跟元素结束事件。而事件处理器则负责对事件作出响应,对传递的 XML 数据进行处理。
在 Python 中使用 sax 方式处理 xml 要先引入 xml.sax 中的 parse 函数,还有 xml.sax.handler 中的 ContentHandler。
ContentHandler 类方法介绍 characters(content)方法: 从行开始,遇到标签之前,存在字符,content 的值为这些字符串。从一个标签,遇到下一个标签之前,存在字符,content 的值为这些字符串。从一个标签,遇到行结束符之前,存在字符,content 的值为这些字符串。标签可以是开始标签,也可以是结束标签。startDocument()方法:文档启动的时候调用。
endDocument()方法:解析器到达文档结尾时调用。
startElement(name, attrs) 方法:遇到XML开始标签时调用,name 是标签的名字,attrs 是标签的属性值字典。
endElement(name) 方法:遇到XML结束标签时调用。
make_parser方法make_parser()方法用于创建一个新的解析器对象并返回。创建的解析器对象将是系统找到的第一个解析器类型。
语法如下:
xml.sax.make_parser(parser_list)parser_list --可选参数,解析器列表 parser方法parser ()方法用于创建一个 SAX 解析器并解析xml文档。
语法如下:
xml.sax.parse( xmlfile, contenthandler[, errorhandler])xmlfile -- xml文件名contenthandler --必须是一个ContentHandler对象errorhandler --如果指定该参数,errorhandler必须是一个SAX ErrorHandler对象 parseString方法parseString()方法创建一个 XML 解析器并解析 xml 字符串。
语法如下:
xml.sax.parseString(xmlstring, contenthandler[, errorhandler])xmlstring -- xml字符串contenthandler --必须是一个ContentHandler的对象errorhandler --如果指定该参数,errorhandler必须是一个SAX ErrorHandler对象 Python 解析XML实例import xml.saxclassMovieHandler(xml.sax.ContentHandler):def __init__(self): self.CurrentData="" self.type ="" self.format ="" self.year ="" self.rating ="" self.stars ="" self.description =""# 元素开始调用def startElement(self, tag, attributes): self.CurrentData= tagif tag =="movie":print("-----电影信息介绍-----") title = attributes["title"]print("Title:", title)# 元素结束调用def endElement(self, tag):if self.CurrentData=="type":print("类型:", self.type)elif self.CurrentData=="format":print("格式:", self.format)elif self.CurrentData=="year":print("时间:", self.year)elif self.CurrentData=="rating":print("评级:", self.rating)elif self.CurrentData=="stars":print("星星:", self.stars)elif self.CurrentData=="description":print("描述:", self.description,"\n") self.CurrentData=""# 读取字符时调用def characters(self, content):if self.CurrentData=="type": self.type = contentelif self.CurrentData=="format": self.format = contentelif self.CurrentData=="year": self.year = contentelif self.CurrentData=="rating": self.rating = contentelif self.CurrentData=="stars": self.stars = contentelif self.CurrentData=="description": self.description = contentif(__name__ =="__main__"):# 创建一个 XMLReader parser = xml.sax.make_parser()# 关闭命名空间 parser.setFeature(xml.sax.handler.feature_namespaces,0)# 重写 ContextHandlerHandler=MovieHandler() parser.setContentHandler(Handler) parser.parse("movies.xml")运行程序后输出结果如下:
-----电影信息介绍-----Title:重返二十岁类型:喜剧,亲情,爱情,奇幻格式: DVD时间:2014评级:7岁以上可以观看星星:8描述:影片讲述了一位七旬老太太不可思议变身为妙龄女子后,以新身份回到日常生活,引发的一系列啼笑皆非的奇幻故事-----电影信息介绍-----Title:流浪地球类型:科幻、灾难、冒险、动作格式: DVD时间:2019评级: R星星:10描述:讲述了太阳即将毁灭,已经不适合人类生存,而面对绝境,人类将开启“流浪地球”计划-----电影信息介绍-----Title:恶棍天使类型:喜剧,爱情格式: DVD时间:2015评级: PG星星:10描述:讲述了高智商低情商女学霸查小刀遇到专职替人讨债的恶棍莫非里,俩人在神医折耳根的介绍下互相“治疗”发生的一系列故事-----电影信息介绍-----Title:战狼类型:动作,战争,军事格式: VHS时间:2015评级: PG星星:10描述:讲述的是小人物成长为拯救国家和民族命运的孤胆英雄的传奇故事 使用DOM API解析XML文档对象模型是来自W3C的跨语言API,用于访问和修改XML文档。
DOM解析器在解析一个XML文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里。之后可以利用DOM 提供的不同的函数来读取或修改文档的内容和结构,也可以把修改过的内容写入xml文件。
使用xml.dom.minidom来解析xml文件时,minidom对象提供了一种简单的解析器方法,可以从XML文件中快速创建DOM树。
示例:from xml.dom.minidom import parseimport xml.dom.minidom# 使用minidom解析器打开XML文档DOMTree= xml.dom.minidom.parse("movies.xml")collection =DOMTree.documentElementif collection.hasAttribute("shelf"):print("根元素 : %s"% collection.getAttribute("shelf"))# 在集合中获取所有电影movies = collection.getElementsByTagName("movie")# 打印每部电影的详细信息for movie in movies:print("-----电影信息介绍-----")if movie.hasAttribute("title"):print("标题: %s"% movie.getAttribute("title")) type = movie.getElementsByTagName(type)[0]print("类型: %s"% type.childNodes[0].data) format = movie.getElementsByTagName(format)[0]print("格式: %s"% format.childNodes[0].data) rating = movie.getElementsByTagName(rating)[0]print("等级: %s"% rating.childNodes[0].data) stars = movie.getElementsByTagName(stars)[0]print("星星: %s"% stars.childNodes[0].data) description = movie.getElementsByTagName(description)[0]print("描述: %s"% description.childNodes[0].data,"\n")运行程序后输出结果如下:
根元素:新品推荐-----电影信息介绍-----标题:重返二十岁类型:喜剧,亲情,爱情,奇幻格式: DVD等级: PG星星:8描述:影片讲述了一位七旬老太太不可思议变身为妙龄女子后,以新身份回到日常生活,引发的一系列啼笑皆非的奇幻故事-----电影信息介绍-----标题:流浪地球类型:科幻、灾难、冒险、动作格式: DVD等级: R星星:10描述:讲述了太阳即将毁灭,已经不适合人类生存,而面对绝境,人类将开启“流浪地球”计划-----电影信息介绍-----标题:恶棍天使类型:喜剧,爱情格式: DVD等级: PG星星:10描述:讲述了高智商低情商女学霸查小刀遇到专职替人讨债的恶棍莫非里,俩人在神医折耳根的介绍下互相“治疗”发生的一系列故事-----电影信息介绍-----标题:战狼类型:动作,战争,军事格式: VHS等级: PG星星:10描述:讲述的是小人物成长为拯救国家和民族命运的孤胆英雄的传奇故事扫一扫,关注我们