凯发娱发k8

python如何实现xml解析 -凯发娱发k8

2024-01-07

这篇文章将为大家详细讲解有关python如何实现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内容如下



  war, thriller
  dvd
  2003
  pg
  10
  talk about a us-japan war

  anime, science fiction
  dvd
  1989
  r
  8
  a schientific fiction
  
  anime, action
  dvd
  4
  pg
  10
  vash the stampede!

  comedy
  vhs
  pg
  2
  viewable boredom

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如何实现xml解析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

网站地图