python有3种方法解析XML:SAX,DOM以及ElemenTree
1.SAX(simple API for XML)
python标准库包含SAX解析器,SAX用事件驱动模型,通过在解析XML的过程中触发事件并调用用户定义的回调函数来处理XML文件
2.DOM(Document Object Model)
将XML数据在内存中解析成一个树,通过对树的操作来操作XML。
movies.xml:
<collection shelf="New Arrivals"> <movie title="Enemy Behind"> <!-- 属性(attribute) --> <type>War, Thriller</type><!-- 元素(element) --> <format>DVD</format> <year>2003</year> <rating>PG</rating> <stars>10</stars> <description>Talk about a US-Japan war</description> </movie> <movie title="Transformers"> <type>Anime, Science Fiction</type> <format>DVD</format> <year>1989</year> <rating>R</rating> <stars>8</stars> <description>A schientific fiction</description> </movie> </collection>
DOM解析文件:
from xml.dom.minidom import parse import xml.dom.minidom # 使用minidom解析器打开 XML 文档 DOMTree = xml.dom.minidom.parse("movies.xml") #minidom.parse加载读取XML文件 collection = DOMTree.documentElement #doc.documentElement 获取XML文档对象 if collection.hasAttribute("shelf"): print ("Root element : %s" % collection.getAttribute("shelf")) #node.getAttribute(AttributeName) #获取XML节点属性值
在集合中获取所有电影
movies = collection.getElementsByTagName("movie") #node.getElementsByTagName(TagName) 获取XML节点对象集合
# 打印每部电影的详细信息
for movie in movies: print ("*****Movie*****") if movie.hasAttribute("title"): print ("Title: %s" % movie.getAttribute("title")) type = movie.getElementsByTagName('type')[0]# [0]:若存在同名的,用以区分 print ("Type: %s" % type.childNodes[0].data) # type.childNodes[0]表示type标签下的第一个内容或者子标签 format = movie.getElementsByTagName('format')[0] print ("Format: %s" % format.childNodes[0].data) rating = movie.getElementsByTagName('rating')[0] print ("Rating: %s" % rating.childNodes[0].data) description = movie.getElementsByTagName('description')[0] print ("Description: %s" % description.childNodes[0].data)
三、常用方法:
minidom.parse(filename) #加载读取XML文件 doc.documentElement #获取XML文档对象 node.getAttribute(AttributeName) #获取XML节点属性值 node.getElementsByTagName(TagName) #获取XML节点对象集合 node.childNodes #返回子节点列表。 node.childNodes[index].nodeValue #获取XML节点值 node.firstChild #访问第一个节点。等价于pagexml.childNodes[0] doc = minidom.parse(filename) doc.toxml('UTF-8') #返回Node节点的xml表示的文本 Node.attributes["id"] #访问元素属性 a.name #就是上面的 "id" a.value #属性的值
sax解析
大型文件读取部分
from xml.sax import parse from xml.sax import ContentHandler class Student: def __init__(self,id=None,name=None,age=None,sex=None): self.name=name self.age=age self.sex=sex self.id=id def __str__(self): return self.id+"-"+self.name+"-"+str(self.age)+"-"+self.sex studengt=[] class saxDamo(ContentHandler): def __init__(self): self.student=None self.tag=None self.id=None def startDocument(self): print("开始--------------") def endDocument(self): print("结束--------------") def startElement(self, name, attrs): #标签的开始从头开始查询从父标签到子标签 if name=="student": self.id=attrs["id"] self.student=Student() print("前标签,标签名字",name,"attrs---------",attrs) def endElement(self, name): if name=='stuname': self.student.name=self.tag if name=='stuage': self.student.age=self.tag if name=="stusex": self.student.sex=self.tag if name=="student": self.student.id=self.id studengt.append(self.student) print("后标签name",name) def characters(self, content): self.tag=content print("前中后中内容content**************",content) parse("Student.xml",saxDamo()) for i in studengt: print(i)
在python中使用sax方式处理xml:
先引入xml.sax中的parse函数、xml.sax.handler中的ContentHandler
1、ContentHandler类方法
2、characters(content)方法
调用时机:从行开始,遇到标签之前,存在字符,content的值为这些字符串
从一个标签,遇到下一个标签之前,存在字符,content的值为这些字符串
从一个标签,遇到行结束符之前,存在字符,content的值为这些字符串
标签可以是开始标签,也可以是结束标签
3、startDocument()方法
文档启动的时候调用
4、endDocument()方法:解析器到达文档结尾时调用
5、startElement(name,attrs)方法:
遇到XML开始标签时调用,name是标签的名字,attrs是标签的属性值字典
6、endElement(name)方法:遇到XML结束标签时调用
7、make_parser方法:创建一个新的解析器对象并返回xml.sax.make_parser([parser_list])。parser_list————可选参数————解析器列表
8、parser方法:创建SAX解析器并解析xml文档,
xml.sax.parse(xmlfile,contenthandler[,errorhandler]) xmlfile - xml文件名 contenthandler - 必须是一个ContentHandler的对象 errorhandler - 如果指定该参数,errorhandler必须是一个SAXErrorHandler对象 '''