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对象 '''