python解析xml

来源:互联网 发布:数据安全 编辑:程序博客网 时间:2024/06/01 21:11

Python解析XML文件

三种方式

  1. SAX(simple api for xml)
  2. DOM(Document Object Moedl)
  3. ElementTree(元素树)

需要解析的xml文件:

<?xml version="1.0" encoding="utf-8" ?><books>    <book id="j01">        <name>java</name>        <price>100</price>        <author>jams</author>    </book>    <book id="c01">        <name>C</name>        <price>200</price>        <author>bart</author>    </book>    <book id="py01">        <name>python</name>        <price>300</price>        <author>lisa</author>    </book>    <book id="c#01">        <name>C#</name>        <price>200</price>        <author>maggie</author>    </book></books>

SAX

事件驱动模式
- 解析器负责读取XML文档,并向事件处理器发送事件,如元素开始跟元素结束事件;
- 而事件处理器则负责对事件作出相应,对传递的XML数据进行处理。
- 解析器负责读取XML文档,并向事件处理器发送事件,如元素开始跟元素结束事件,而事件处理器则负责对事件作出相应,对传递的XML数据进行处理。

1、对大型文件进行处理;
2、只需要文件的部分内容,或者只需从文件中得到特定信息。
3、想建立自己的对象模型的时候。
在python中使用sax方式处理xml要先引入xml.sax中的parse函数,还有xml.sax.handler中的ContentHandler。

ContentHandler类方法介绍

  1. characters(content)方法
    调用时机:

    • 从行开始,遇到标签之前,存在字符,content的值为这些字符串。
    • 从一个标签,遇到下一个标签之前, 存在字符,content的值为这些字符串。
    • 从一个标签,遇到行结束符之前,存在字符,content的值为这些字符串。
    • 标签可以是开始标签,也可以是结束标签。
  2. startDocument()方法
    文档启动的时候调用。

  3. endDocument()方法
    解析器到达文档结尾时调用。

  4. startElement(name, attrs)方法
    遇到XML开始标签时调用,name是标签的名字,attrs是标签的属性值字典。

  5. endElement(name)方法

遇到XML结束标签时调用。

  1. make_parser方法
    以下方法创建一个新的解析器对象并返回。

xml.sax.make_parser( [parser_list] )
参数说明:
- parser_list - 可选参数,解析器列表

  1. parser方法
    以下方法创建一个 SAX 解析器并解析xml文档:

xml.sax.parse( xmlfile, contenthandler[, errorhandler])
参数说明:
- xmlfile - xml文件名
- contenthandler - 必须是一个ContentHandler的对象
- errorhandler - 如果指定该参数,errorhandler必须是一个SAX ErrorHandler对象

  1. parseString方法

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:javaprice:100author:jams===book (id= c01)name:Cprice:200author:bart===book (id= py01)name:pythonprice:300author:lisa===book (id= c#01)name:C#price:200author:maggie

DOM

将 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.documentElementprint("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:<DOM Element: books at 0x229a470>***book id=j01name:javaprice:100author:jams***book id=c01name:Cprice:200author:bart***book id=py01name:pythonprice:300author:lisa***book id=c#01name:C#price:200author:maggie

ElementTree

类似一个轻量级的dom 消耗内存少
- parse(<路径>):
返回一个xml.etree.ElementTree.ElementTree对象
- findall(“./<标签>”):
返回一个list对象 ,存放着指定标签的xml.etree.ElementTree.Element元素对象

# 从xml.etree 模块中 导入ElementTree并取别名为 etfrom 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:javaprice:100author:jams******************name:Cprice:200author:bart******************name:pythonprice:300author:lisa******************name:C#price:200author:maggie******************
原创粉丝点击