python实现XML解析的方法解析


Posted in Python onNovember 16, 2019

这篇文章主要介绍了python实现XML解析的方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

三种方法:一是xml.dom.*模块,它是W3C DOM API的实现,若需要处理DOM API则该模块很适合;二是xml.sax.*模块,它是SAX API的实现,这个模块牺牲了便捷性来换取速度和内存占用,SAX是一个基于事件的API,这就意味着它可以“在空中”处理庞大数量的的文档,不用完全加载进内存;三是xml.etree.ElementTree模块(简称 ET),它提供了轻量级的Python式的API,相对于DOM来说ET 快了很多,而且有很多令人愉悦的API可以使用,相对于SAX来说ET的ET.iterparse也提供了 “在空中” 的处理方式,没有必要加载整个文档到内存,ET的性能的平均值和SAX差不多,但是API的效率更高一点而且使用起来很方便。

1、DOM(Document Object Model)

一个 DOM 的解析器在解析一个 XML 文档时,一次性读取整个文档,把文档中所有元素保存在内存中的一个树结构里,之后你可以利用DOM 提供的不同的函数来读取或修改文档的内容和结构,也可以把修改过的内容写入xml文件。

python中用xml.dom.minidom来解析xml文件。

本文使用的示例文件movie.xml内容如下

<collection shelf="New Arrivals">
<movie title="Enemy Behind">
  <type>War, Thriller</type>
  <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>
  <movie title="Trigun">
  <type>Anime, Action</type>
  <format>DVD</format>
  <episodes>4</episodes>
  <rating>PG</rating>
  <stars>10</stars>
  <description>Vash the Stampede!</description>
</movie>
<movie title="Ishtar">
  <type>Comedy</type>
  <format>VHS</format>
  <rating>PG</rating>
  <stars>2</stars>
  <description>Viewable boredom</description>
</movie>
</collection>

python实现如下

# !/usr/bin/python
# -*- coding: UTF-8 -*-

from xml.dom.minidom import parse
import xml.dom.minidom

# 使用minidom解析器打开 XML 文档
DOMTree = xml.dom.minidom.parse("movie.xml")
#得到元素对象
collection = DOMTree.documentElement
if collection.hasAttribute("shelf"):
  print("Root element : %s" % collection.getAttribute("shelf"))
  #获取标签名
  #print(collection.nodeName)

# 在集合中获取所有电影
movies = collection.getElementsByTagName("movie")

# 打印每部电影的详细信息
for movie in movies:
  print("*****Movie*****")
  if movie.hasAttribute("title"):
    print("Title: %s" % movie.getAttribute("title"))

  type = movie.getElementsByTagName('type')[0]
  print("Type: %s" % type.childNodes[0].data)
  format = movie.getElementsByTagName('format')[0]
  print("Format: %s" % format.childNodes[0].data)
  year=movie.getElementsByTagName("year")
  if len(year)>0:
    print("Year: %s" % year[0].firstChild.data)
    #父节点 parentNode
    #print(year[0].parentNode.nodeName)
  rating = movie.getElementsByTagName('rating')[0]
  print("Rating: %s" % rating.childNodes[0].data)
  description = movie.getElementsByTagName('description')[0]
  # 显示标签对之间的数据
  print("Description: %s" % description.childNodes[0].data)
  #print("Description: %s" % description.firstChild.data)

执行结果:

Root element : New Arrivals
*****Movie*****
Title: Enemy Behind
Type: War, Thriller
Format: DVD
Year: 2003
Rating: PG
Description: Talk about a US-Japan war
*****Movie*****
Title: Transformers
Type: Anime, Science Fiction
Format: DVD
Year: 1989
Rating: R
Description: A schientific fiction
*****Movie*****
Title: Trigun
Type: Anime, Action
Format: DVD
Rating: PG
Description: Vash the Stampede!
*****Movie*****
Title: Ishtar
Type: Comedy
Format: VHS
Rating: PG
Description: Viewable boredom

2、ElementTree(元素树)

ElementTree就像一个轻量级的DOM,具有方便友好的API。代码可用性好,速度快,消耗内存少。

在python中,解析xml文件时,会选用ElementTree或者cElementTree,那么两者有什么不同呢?

1、cElementTree速度上要比ElementTree快,比较cElementTree是用c语音写的;

2、debug调试的时候,cElementTree是看不到解析的字段内容的,所以不适合用于调试的情况,而ElementTree可以看到解析的内容,方便调试时取值

3、在用到iter,迭代取某个标签时,cElementTree不能用,因为它没有这个函数,而ElementTree有这个函数;当然可能还有其他函数的差异

所有平时,我们一般这么用,比较速度快吗。调试的时候使用ElementTree。遇到某些特别的函数,只能选择拥有这个函数的使用

try:

import xml.etree.cElementTree as ET

except:

import xml.etree.ElementTree as ET

从Python3.3开始ElementTree模块会自动寻找可用的C库来加快速度

import xml.etree.ElementTree as ET
import sys
import os.path

def traverseXml(element):
  #print (len(element))
  if len(element) > 0:
    for child in element:
      print("********Movie********")
      print("Title:",child.get("title"))
      for childchild in child:
        print(childchild.tag,":",childchild.text)
      #traverseXml(child)
  #else:
  #  print (element.tag, "----", element.attrib)

def readXml(xmlFile):
  try:
    tree = ET.parse(xmlFile)
    #print("tree type:", type(tree))
    # 获得根节点
    root = tree.getroot()
  except Exception as e: # 捕获除与程序退出sys.exit()相关之外的所有异常
    print("parse ***.xml fail!")
    sys.exit()
  #print("root type:", type(root))
  #root.attrib访问root属性,root.tag标签
  #print(root.tag, ":", root.attrib)
  return root

if __name__ == "__main__":
  xmlFilePath = os.path.abspath("movie.xml")
  root=readXml(xmlFilePath)

  # # 使用下标访问
  # print(root[0][0].text)
  # print(root[1][2].text)
  #根据标签名查找root下的所有标签
  # movies=root.findall("movie")
  #遍历子标签
  # print(len(movies))
  # for movie in movies:
  #   type=movie.find("type")
  #   print(type.text)

  # 遍历xml文件
  traverseXml(root)

3、SAX (simple API for XML )

Python 标准库包含 SAX 解析器,SAX 用事件驱动模型,通过在解析XML的过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件。

SAX是一种基于事件驱动的 API。

利用SAX解析XML文档牵涉到两个部分: 解析器和事件处理器。

解析器负责读取XML文档,并向事件处理器发送事件,如元素开始跟元素结束事件。

而事件处理器则负责对事件作出响应,对传递的XML数据进行处理。

  • 1、对大型文件进行处理;
  • 2、只需要文件的部分内容,或者只需从文件中得到特定信息。
  • 3、想建立自己的对象模型的时候。

在python中使用sax方式处理xml要先引入xml.sax中的parse函数,还有xml.sax.handler中的ContentHandler。

ContentHandler类方法介绍

characters(content)方法

调用时机:

从行开始,遇到标签之前,存在字符,content 的值为这些字符串。

从一个标签,遇到下一个标签之前, 存在字符,content 的值为这些字符串。

从一个标签,遇到行结束符之前,存在字符,content 的值为这些字符串。

标签可以是开始标签,也可以是结束标签。

startDocument() 方法

文档启动的时候调用。

endDocument() 方法

解析器到达文档结尾时调用。

startElement(name, attrs)方法

遇到XML开始标签时调用,name是标签的名字,attrs是标签的属性值字典。

endElement(name) 方法

遇到XML结束标签时调用。

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import xml.sax

class MovieHandler(xml.sax.ContentHandler):
  def __init__(self):
    self.CurrentData = ""
    self.type = ""
    self.format = ""
    self.year = ""
    self.rating = ""
    self.stars = ""
    self.description = ""

  # 元素开始事件处理
  def startElement(self, tag, attributes):
    self.CurrentData = tag
    if tag == "movie":
      print("*****Movie*****")
      title = attributes["title"]
      print("Title:", title)

  # 元素结束事件处理
  def endElement(self, tag):
    if self.CurrentData == "type":
      print("Type:", self.type)
    elif self.CurrentData == "format":
      print("Format:", self.format)
    elif self.CurrentData == "year":
      print("Year:", self.year)
    elif self.CurrentData == "rating":
      print("Rating:", self.rating)
    elif self.CurrentData == "stars":
      print("Stars:", self.stars)
    elif self.CurrentData == "description":
      print("Description:", self.description)
    self.CurrentData = ""

  # 内容事件处理
  def characters(self, content):
    if self.CurrentData == "type":
      self.type = content
    elif self.CurrentData == "format":
      self.format = content
    elif self.CurrentData == "year":
      self.year = content
    elif self.CurrentData == "rating":
      self.rating = content
    elif self.CurrentData == "stars":
      self.stars = content
    elif self.CurrentData == "description":
      self.description = content

if (__name__ == "__main__"):
  # 创建一个 XMLReader
  parser = xml.sax.make_parser()
  # turn off namepsaces
  parser.setFeature(xml.sax.handler.feature_namespaces, 0)

  # 重写 ContextHandler
  Handler = MovieHandler()
  parser.setContentHandler(Handler)

  parser.parse("movie.xml")

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中使用socket发送HTTP请求数据接收不完整问题解决方法
Feb 04 Python
实例说明Python中比较运算符的使用
May 13 Python
详解Python中的__getitem__方法与slice对象的切片操作
Jun 27 Python
Python的面向对象编程方式学习笔记
Jul 12 Python
使用Turtle画正螺旋线的方法
Sep 22 Python
python实现词法分析器
Jan 31 Python
Tensorflow实现部分参数梯度更新操作
Jan 23 Python
python ffmpeg任意提取视频帧的方法
Feb 21 Python
python 插入日期数据到Oracle实例
Mar 02 Python
Django 拼接两个queryset 或是两个不可以相加的对象实例
Mar 28 Python
python调用摄像头的示例代码
Sep 28 Python
pycharm 多行批量缩进和反向缩进快捷键介绍
Jan 15 Python
Python实现自定义读写分离代码实例
Nov 16 #Python
Python大数据之网络爬虫的post请求、get请求区别实例分析
Nov 16 #Python
基于python实现雪花算法过程详解
Nov 16 #Python
Python大数据之使用lxml库解析html网页文件示例
Nov 16 #Python
Python大数据之从网页上爬取数据的方法详解
Nov 16 #Python
简单了解Pandas缺失值处理方法
Nov 16 #Python
python selenium 执行完毕关闭chromedriver进程示例
Nov 15 #Python
You might like
php获取访问者IP地址汇总
2015/04/24 PHP
简单JS代码压缩器
2006/10/12 Javascript
利用JS重写Cognos右键菜单的实现代码
2010/04/11 Javascript
window.name代替cookie的实现代码
2010/11/28 Javascript
简约JS日历控件 实例代码
2013/07/12 Javascript
Javascript验证上传图片大小[前台处理]
2014/07/18 Javascript
jQuery不使用插件及swf实现无刷新文件上传
2014/12/08 Javascript
JavaScript判断变量是否为空的自定义函数分享
2015/01/31 Javascript
jQuery Uploadify 上传插件出现Http Error 302 错误的解决办法
2015/12/12 Javascript
jquery.cookie.js用法实例详解
2015/12/25 Javascript
JS和jQuery使用submit方法无法提交表单的原因分析及解决办法
2016/05/17 Javascript
Vue.js实战之通过监听滚动事件实现动态锚点
2017/04/04 Javascript
JS使用贪心算法解决找零问题示例
2017/11/27 Javascript
jquery实现动态添加附件功能
2018/10/23 jQuery
基于jquery ajax的多文件上传进度条过程解析
2019/09/11 jQuery
JS数组降维的实现Array.prototype.concat.apply([], arr)
2020/04/28 Javascript
解决VUE 在IE下出现ReferenceError: Promise未定义的问题
2020/11/07 Javascript
[02:44]完美大师赛主赛事淘汰赛第二日观众采访
2017/11/24 DOTA
Python 文件读写操作实例详解
2014/03/12 Python
Python open()文件处理使用介绍
2014/11/30 Python
PyCharm使用教程之搭建Python开发环境
2016/06/07 Python
python爬虫之urllib,伪装,超时设置,异常处理的方法
2018/12/19 Python
python 3.7.4 安装 opencv的教程
2019/10/10 Python
Python 脚本实现淘宝准点秒杀功能
2019/11/13 Python
python 用 xlwings 库 生成图表的操作方法
2019/12/22 Python
基于plt.title无法显示中文的快速解决
2020/05/16 Python
建筑自我鉴定
2013/10/19 职场文书
以幸福为主题的活动方案
2014/08/22 职场文书
2014年全国法制宣传日宣传活动方案
2014/11/02 职场文书
党校学习党性分析材料
2014/12/19 职场文书
实习护士自荐信
2015/03/25 职场文书
月考总结与反思
2015/10/22 职场文书
动漫APP软件排行榜前十名,半次元上榜,第一款由腾讯公司推出
2022/03/18 杂记
详解使用内网穿透工具Ngrok代理本地服务
2022/03/31 Servers
Redis 限流器
2022/05/15 Redis
Spring Cloud OpenFeign模版化客户端
2022/06/25 Java/Android