个性化阅读
专注于IT技术分析

python XML处理 – Python高级开发教程

上一章Python教程请查看:python多线程编程

XML是一种可移植的开放源码语言,它允许程序员开发可以被其他应用程序读取的应用程序,而不必考虑操作系统和/或开发语言。

一、XML是什么?

可扩展标记语言(XML)是一种类似于HTML或SGML的标记语言,这是由万维网联盟推荐的开放标准。

在不需要基于sql的主干的情况下,XML对于跟踪中小型数据非常有用。

二、XML解析器体系结构和api

Python标准库提供了一组用于处理XML的最小但有用的接口。

用于XML数据的两个最基本和最广泛使用的api是SAX和DOM接口。

  • XML的简单API (SAX)——在这里为感兴趣的事件注册回调,然后让解析器遍历文档。当你的文档很大或有内存限制时,这是很有用的,它在从磁盘读取文件时解析文件,而整个文件从不存储在内存中。
  • 文档对象模型(Document Object Model, DOM) API——这是一个万维网联盟的建议,其中将整个文件读入内存并以分层(基于树)的形式存储,以表示XML文档的所有特性。

在处理大文件时,SAX显然不能像DOM那样快速地处理信息。另一方面,仅使用DOM确实会消耗资源,特别是在许多小文件上。

SAX是只读的,而DOM允许更改XML文件。由于这两个不同的api实际上是互补的,所以没有理由不能在大型项目中同时使用它们。

对于我们所有的XML代码示例,让我们使用一个简单的XML文件movies.xml作为输入:

<collection shelf="New Movies">
<movie title="Black Forest">
   <type>Thriller</type>
   <format>DVD</format>
   <year>2018</year>
   <rating>PG</rating>
   <stars>3</stars>
   <description>Talk about black</description>
</movie>
<movie title="Once Up On A Time">
   <type>Science Fiction</type>
   <format>DVD</format>
   <year>1989</year>
   <rating>R</rating>
   <stars>8</stars>
   <description>once up on a time, there</description>
</movie>
   <movie title="Music">
   <type>Action</type>
   <format>DVD</format>
   <episodes>4</episodes>
   <rating>PG</rating>
   <stars>8</stars>
   <description>balabala…</description>
</movie>
<movie title="Funny Pig">
   <type>Comedy</type>
   <format>VHS</format>
   <rating>PG</rating>
   <stars>2</stars>
   <description>a sotry about a donkey and a pig</description>
</movie>
</collection>

三、使用SAX api解析XML

SAX是事件驱动XML解析的标准接口,使用SAX解析XML通常需要通过子类化xml.sax.ContentHandler来创建自己的ContentHandler。

ContentHandler处理XML的特定标记和属性,ContentHandler对象提供了处理各种解析事件的方法,它的解析器在解析XML文件时调用ContentHandler方法。

方法startDocument和endDocument在XML文件的开头和结尾调用,方法characters(文本)通过参数文本传递XML文件的字符数据。

ContentHandler在每个元素的开头和结尾调用,如果解析器不在名称空间模式,则调用startElement(标记、属性)和endElement(标记)方法,否则将调用相应的方法startElementNS和endElementNS,这里tag是元素标记,attributes是attributes对象。

这里有一些重要的方法,你必须先了解,然后才能继续

1、make_parser方法

下面的方法创建一个新的解析器对象并返回它,所创建的解析器对象是系统找到的第一个解析器类型。

xml.sax.make_parser( [parser_list] )

这里是参数的细节:

parser_list——一个可选的参数,它包含一个要使用的解析器列表,所有这些解析器都必须实现make_parser方法。

2、parse方法

下面的方法创建一个SAX解析器并使用它解析文档。

xml.sax.parse( xmlfile, contenthandler[, errorhandler])

这里是参数的细节:

  • xmlfile——这是要从中读取的XML文件的名称。
  • contenthandler——这一定是一个ContentHandler对象。
  • 如果指定了errorhandler,则errorhandler必须是SAX errorhandler对象。

3、parseString方法

还有一个方法用于创建SAX解析器和解析指定的XML字符串。

xml.sax.parseString(xmlstring, contenthandler[, errorhandler])

这里是参数的细节:

  • xmlstring——这是要读取的XML字符串的名称。
  • contenthandler——这一定是一个ContentHandler对象。
  • 如果指定了errorhandler,则errorhandler必须是SAX errorhandler对象。
#!/usr/bin/python

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()
   # 关闭命名空间
   parser.setFeature(xml.sax.handler.feature_namespaces, 0)

   # 覆盖默认的ContextHandler
   Handler = MovieHandler()
   parser.setContentHandler( Handler )
   
   parser.parse("movies.xml")

有关SAX API文档的完整细节,请参阅标准Python SAX API。

四、使用DOM api解析XML

文档对象模型(“DOM”)是来自万维网联盟(W3C)的跨语言API,用于访问和修改XML文档。

DOM对于随机访问应用程序非常有用,SAX一次只允许查看文档的一部分,如果查看一个SAX元素,则无法访问另一个元素。

下面是快速加载XML文档和使用XML创建minidom对象的最简单方法,xml.dom模块minidom对象提供了一个简单的解析器方法,可以从XML文件快速创建DOM树。

示例调用minidom对象的parse(file [,parser])函数,将文件指定的XML文件解析为DOM树对象。

#!/usr/bin/python

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

# 使用minidom解析器打开XML文档
DOMTree = xml.dom.minidom.parse("movies.xml")
collection = DOMTree.documentElement
if collection.hasAttribute("shelf"):
   print "Root element : %s" % collection.getAttribute("shelf")

# 获取所有movie
movies = collection.getElementsByTagName("movie")

# 打印每个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
   rating = movie.getElementsByTagName('rating')[0]
   print "Rating: %s" % rating.childNodes[0].data
   description = movie.getElementsByTagName('description')[0]
   print "Description: %s" % description.childNodes[0].data

有关DOM API文档的完整细节,请参阅标准Python DOM API

赞(0)
未经允许不得转载:srcmini » python XML处理 – Python高级开发教程

评论 抢沙发

评论前必须登录!