您的位置:首页 > 编程语言 > Python开发

XML学习以及python解析xml笔记

2016-11-25 23:43 507 查看
一:什么是XML

XML是指可扩展标记语言(eXtensible Markup Language)。XML被设计用来传输和存储数据。XML是一套定义语义标记的

规则,这些标记将文档分成许多部件并对这些部件加以标识。

它是无标记语言,即定义了用于定义其他与特定领域有关的,语义的,结构化的标记语言的句法语言。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

三个属性分别是:

version:版本

encoding:编码,UTF-8,GBK等

standalone:表明该xml文件是否和一个独立的标记声明文件配套使用,如果该属性为"yes",说明不需要另外的DTD文件或XSL文件。一般都是"yes"

XML文件的逻辑结构:

1.标记命名的合法性

标记应该以字母,下划线或者冒号开头,中间不能有空格,不能以xml起始。但最好不要用冒号。

2.有效使用属性

标记中可以包含任意多个属性。在标记中,属性以名称/取值对出现,属性名不能重复,名称与取值之间用“=”分隔,且取值用引号引起来。

如:<商品 类型=“服装” 颜色=”黄色“>,XML中属性的取值必须用引号引起来。

3.属性的所有赋值都被看作是字符串。如:<圆柱体 半径="10" 高="30"> 程序应该能够把字符串"10"和"13"转化为

它们代表的数字。

注释:形式为:<!-- <dd></dd>一个XML的例子 -->,注意在注释文本中不能出现字符串"--",不要把注释文本放在标记之中,也不要放在实体

声明中,否则就不是“形式良好”。

二:python对XML的解析

常见的XML编程接口有DOM和SAX,ElementTree。

下面来分别讨论一下它们的区别:

DOM:xml.dom实现的是W3C制定的DOM API,DOM解析器在任何处理开始之前,必须把基于XML文件生成的树状数据放在内存,所以DOM解析器的内存使用量完全根据输入

资料的大小。

SAX:xml.sax模块实现的是SAX API,这个模块牺牲了便捷性来换取速度和内存占用。它是事件驱动的,并不需要一次性读入整个文档,而文档的读入过程也就是SAX

的解析过程。所谓事件驱动,即基于回调。

ElementTree:xml.etree.ElementTree模块提供了一个轻量级、Pythonic的API,同时还有一个高效的C语言实现,即xml.etree.cElementTree。与DOM相比,ET的速度更快,

API的使用更直接,方便。与SAX相比,ET.iterparse函数同样提供了按需解析的功能,不会一次性在内存读入整个文档。ET的性能与SAX模块大致相仿,但是它的API

更加方便。

如何使用SAX

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

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

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

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

(1)对大型文件进行处理

(2)只需要文件的部分内容,或者只需从文件中的到特定信息

(3) 想建立自己的对象模型的时候

在python中使用sax的方式处理xml要先引入xml.sax中的parse函数,还有xml.sax.handler中的ContentHandler。(即一个解析,一个处理)

解析parser.py文件:

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__"):

parser = xml.sax.make_parser()
# turn off namepsaces
parser.setFeature(xml.sax.handler.feature_namespaces, 0)

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

parser.parse("movies.xml")


movies.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>


输出:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: