需要解析的xml文件:
<books>
<book id="j01">
<name>javaname>
<price>100price>
<author>jamsauthor>
book>
<book id="c01">
<name>Cname>
<price>200price>
<author>bartauthor>
book>
<book id="py01">
<name>pythonname>
<price>300price>
<author>lisaauthor>
book>
<book id="c#01">
<name>C#name>
<price>200price>
<author>maggieauthor>
book>
books>
事件驱动模式
- 解析器负责读取XML文档,并向事件处理器发送事件,如元素开始跟元素结束事件;
- 而事件处理器则负责对事件作出相应,对传递的XML数据进行处理。
- 解析器负责读取XML文档,并向事件处理器发送事件,如元素开始跟元素结束事件,而事件处理器则负责对事件作出相应,对传递的XML数据进行处理。
1、对大型文件进行处理;
2、只需要文件的部分内容,或者只需从文件中得到特定信息。
3、想建立自己的对象模型的时候。
在python中使用sax方式处理xml要先引入xml.sax中的parse函数,还有xml.sax.handler中的ContentHandler。
characters(content)方法
调用时机:
startDocument()方法
文档启动的时候调用。
endDocument()方法
解析器到达文档结尾时调用。
startElement(name, attrs)方法
遇到XML开始标签时调用,name是标签的名字,attrs是标签的属性值字典。
endElement(name)方法
遇到XML结束标签时调用。
xml.sax.make_parser( [parser_list] )
参数说明:
- parser_list
- 可选参数,解析器列表
xml.sax.parse( xmlfile, contenthandler[, errorhandler])
参数说明:
- xmlfile
- xml文件名
- contenthandler
- 必须是一个ContentHandler的对象
- errorhandler
- 如果指定该参数,errorhandler必须是一个SAX ErrorHandler对象
parseString方法创建一个XML解析器并解析xml字符串:
xml.sax.parseString(xmlstring, contenthandler[, errorhandler])
参数说明:
- xmlstring
- xml字符串
- contenthandler
- 必须是一个ContentHandler的对象
- errorhandler
- 如果指定该参数,errorhandler必须是一个SAX ErrorHandler对象
代码实例:
# 解析 xml 文件对象
import xml.sax
# 继承 xml.sax.ContentHandler 对象
# 实现原理,当开始解析标签的时候调用startElement方法
# 解析标签内容的时候调用characters方法
# 解析完标签之后调用endElement方法
class BookHandler(xml.sax.ContentHandler):
# 构造函数
def __init__(self):
self.CurrentData = ""
self.name = ""
self.price = ""
self.author = ""
# 元素开始事件处理
def startElement(self,tag,attributes):
self.CurrentData = tag
if tag == "book":
print("===%s (id= %s)"%(tag,attributes["id"]))
# 元素内容处理事件
def characters(self,content):
if self.CurrentData == "name":
self.name = content
elif self.CurrentData == "price":
self.price = content
elif self.CurrentData == "author":
self.author = content
# 元素结束事件处理
def endElement(self,tag):
if self.CurrentData == "name":
print("name:"+self.name)
elif self.CurrentData == "price":
print("price:"+self.price)
elif self.CurrentData == "author":
print("author:"+self.author)
self.CurrentData = ""
# main 方法
if( __name__ == "__main__" ):
# 创建一个XMLReader
parser = xml.sax.make_parser()
# 关闭命名空间
parser.setFeature(xml.sax.handler.feature_namespaces,0)
# 重写 ContextHandler,即自定义的类赋值给Handler
Handler = BookHandler()
# 设置解析器
parser.setContentHandler(Handler)
# 开始解析 xml 文件
parser.parse("book.xml")
输出结果:
===book (id= j01)
name:java
price:100
author:jams
===book (id= c01)
name:C
price:200
author:bart
===book (id= py01)
name:python
price:300
author:lisa
===book (id= c#01)
name:C#
price:200
author:maggie
将 xml 文件在内存中解析成一个 树,通过对树的遍历操作xml
文件对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展置标语言的标准编程接口。
一个 DOM 的解析器在解析一个 XML 文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,之后
你可以利用DOM 提供的不同的函数来读取或修改文档的内容和结构,也可以把修改过的内容写入xml文件。
# 导解析器的包
from xml.dom.minidom import parse
# 导 minidom 的包
import xml.dom.minidom
# 解析器解析整个xml文档
DOMTree = parse("book.xml")
# 获得根节点
root = DOMTree.documentElement
print("root element is:%s"%(root))
# 获得所有 book 节点
books = DOMTree.getElementsByTagName("book")
# 遍历
for book in books :
# 打印 book 节点的 id 属性
print("***book id=%s"%(book.getAttribute("id")))
# 获得 name 属性的第一个元素对象,获得该元素对象的第一个子节点对象的 data
name = book.getElementsByTagName("name")[0].childNodes[0].data
print("name:%s"%(name))
price = book.getElementsByTagName("price")[0].childNodes[0].data
print("price:%s"%(price))
author = book.getElementsByTagName("author")[0].childNodes[0].data
print("author:%s"%(author))
输出结果:
root element is:0x229a470>
***book id=j01
name:java
price:100
author:jams
***book id=c01
name:C
price:200
author:bart
***book id=py01
name:python
price:300
author:lisa
***book id=c#01
name:C#
price:200
author:maggie
类似一个轻量级的dom 消耗内存少
- parse(<路径>):
返回一个xml.etree.ElementTree.ElementTree对象
- findall(“./<标签>”):
返回一个list对象 ,存放着指定标签的xml.etree.ElementTree.Element元素对象
# 从xml.etree 模块中 导入ElementTree并取别名为 et
from xml.etree import ElementTree as et
# 解析xml文件
per = et.parse("book.xml")
# 从哪个标签开始解析
p = per.findall("./book")
# 开始遍历 对应的标签拥有的子标签
for item in p:
for node in item:
print(node.tag+":"+node.text)
print("******************")
输出结果:
name:java
price:100
author:jams
******************
name:C
price:200
author:bart
******************
name:python
price:300
author:lisa
******************
name:C#
price:200
author:maggie
******************