python XML

本文介绍了Python解析XML的三种方式:SAX、DOM和ElementTree。SAX采用事件驱动模式,适合处理大型文件或只需要部分信息的情况。DOM将整个XML文档加载到内存中形成树形结构,方便遍历和修改。ElementTree是轻量级的DOM实现,内存消耗较小。文章详细阐述了每种方法的工作原理和使用示例。
摘要由CSDN通过智能技术生成

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

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")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

输出结果:

===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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

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.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))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

输出结果:

root element is:<DOM Element: books at 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

ElementTree

类似一个轻量级的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("******************")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

输出结果:

name:java
price:100
author:jams
******************
name:C
price:200
author:bart
******************
name:python
price:300
author:lisa
******************
name:C#
price:200
author:maggie
******************
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值