python学习18

xml解析

一、xml简介

XML 被设计用来传输和存储数据。

HTML 被设计用来显示数据。

1).什么是xml

  • XML 指可扩展标记语言(EXtensible Markup Language)。
  • XML 是一种很像HTML的标记语言。
  • XML 的设计宗旨是传输数据,而不是显示数据。
  • XML 标签没有被预定义。您需要自行定义标签。
  • XML 被设计为具有自我描述性。
  • XML 是 W3C 的推荐标准。

2).xml和html的区别

XML 不是 HTML 的替代。

XML 和 HTML 为不同的目的而设计:

  • XML 被设计用来传输和存储数据,其焦点是数据的内容。
  • HTML 被设计用来显示数据,其焦点是数据的外观。

HTML 旨在显示信息,而 XML 旨在传输信息。

***

XML 被设计用来结构化、存储以及传输信息。所以XML 不会做任何事情。

XML 语言没有预定义的标签。所以我们可以自定义标签,注意,尽量不定义关键字标签。

XML是对HTML的补充,但不是HTML的替代,在大多数 Web 应用程序中,XML 用于传输数据,而 HTML 用于格式化并显示数据。

XML 是独立于软件和硬件的信息传输工具。

python对XML的解析

常见的XML编程接口有DOM和SAX,这两种接口处理XML文件的方式不同,当然使用场合也不同。

python有三种方法解析XML,SAX,DOM,以及ElementTree:

方法 特点
SAX SAX解析通过流模式在解析XML的过程中触发对应的事件(start_element、char_data、end_element)并调用用户定义的回调函数来处理XML文件。
DOM 将XML数据在内存中解析成一个树,通过对树的操作来操作XML,占用内存大,解析速度较慢,优点是可以任意遍历树的节点。
ElementTree 类似一个轻量级的DOM

我们先使用ElementTree解析一个XML文件,文件如下

<?xml version="1.0" encoding='utf-8'?>   #申明为XML

<data>           #父节点
    <country name="Liechtenstein">      #子节点
        <rank>1</rank>      #子节点的子节点
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>

解析代码如下:

#usr/bin/python
#-*-coding:utf-8-*-
import xml.etree.ElementTree as ET
'''
tag ,即标签,用于标识该元素表示哪种数据,即APP_KEY
attrib,即属性,用Dictionary形式保存,即{'channel'='CSDN'}
text ,文本字符串,可以用来存储一些数据,即hello123456789
'''
#先加载文档到内存里,形成一个倒桩的树结构
tree = ET.parse('huihui.xml')
#获取根节点
root = tree.getroot()
huihui={}
for ele in root:
    value=[]
    for e in ele:
        if e.text is None:
            value.append(e.attrib)
        else:
            value.append({e.tag:e.text})
    huihui[ele.attrib['name']]=value
print(huihui)

上述代码我们先引用了一个xml.etree.ElementTree库,并另取名ET,然后加载文档到tree内存中,形成一个倒桩的树结构,然后我们获取了文本的根节点root。建立一个for循环,让ele遍历root,得到根节点(即country),然后再使e遍历ele,获取到子节点,再进行判断,子节点中是否存在文本,如果不存在,在value列表中追加子节点的属性,如果存在,则以tag为key,以text为value的字典模式追加到value的列表中,最后我们以ele的属性名为key,对应的value列表value放在字典huihui中,输出huihui。

我们还可以查找需要的根/子节点,并修改,如下:

#仍以上述为模板
nodes=root.findall('country')
for node in nodes:
    if node.attrib['name']=='Liechtenstein':
        root.remove(node)

tree.write('huihuihui.xml')
print('删除成功')

首先获取root中名为'country'的根节点,然后循环遍历,寻找属性名为'liechtenstein'的子节点,找到之后将其删除。

下面我们使用SAX解析XML

SAX是事件驱动的XML解析的标准接口。 使用SAX解析XML通常需要通过子类化xml.sax.ContentHandler来创建自己的ContentHandler
ContentHandler处理XML样式/风格的特定标签和属性。 ContentHandler对象提供了处理各种解析事件的方法。它拥有的解析器在解析XML文件时调用ContentHandler方法。
在XML文件的开头和结尾分别调用:startDocument和endDocument方法。 characters(text)方法通过参数text传递XML文件的字符数据。

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

我们使用如下一个XML实践:

<?xml version="1.0" encoding="utf-8" ?>
<collection shelf = "New Arrivals">
    <movie title = "Enemy Behind">
       <type>War, Thriller</type>
       <format>DVD</format>
       <year>2013</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>

代码如下:

#usr/bin/python
#-*-coding:utf-8-*-
import xml.sax
#首先引用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 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

    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 = ""



if (__name__ == "__main__"):
    # 1 创建一个XMLReader
    parser = xml.sax.make_parser()
    # 2关闭命名空间 namepsaces工作目录 工作空间 命名空间
    parser.setFeature(xml.sax.handler.feature_namespaces, 0)
    # 3 覆盖默认的 ContextHandler
    Handler = MovieHandler()
    parser.setContentHandler(Handler)  #  设置当前的ContentHandler为我们自己写的handler实例。
    #parse() 加载
    parser.parse("movie.xml")    #上述的xml存储在movie.xml中

我们先创建一个类,然后初始化参数(根据要解析的xml中的参数),使用startElement,将获取到的值赋值给CurrentDate,然后判断CurrentDate的值是否为movie,如果是,打印一个*****movie*****,并给title赋值获取节点的属性名,在打印出来。如果值不为movie,则依次判断CurrentDate的值为哪个参数,判断到了,则赋值给那个参数,然后在endElement中将对应的值打印,最后再清除CurrentDate的值,然后继续循环下一个节点,所以整个类是将XML中每一个节点都查找一遍,根据对应的值将其打印的模式进行。最终输出一下结果:

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




猜你喜欢

转载自blog.csdn.net/gy_334/article/details/80490924
今日推荐