zoukankan      html  css  js  c++  java
  • Etree方式解析xml知识积累

    1. 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>
    2. 遍历 xml 文件:

    >>> import sys

    >>> try:

    ...     import xml.etree.cElementTree as ET

    ... except ImportError:

    ...     import xml.etree.ElementTree as ET

    ...

    导入包,推荐使用cElementTree,效率高(带C的效率高)

    >>> tree = ET.ElementTree(file='e:\movie.xml')

    >>> root = tree.getroot()

    >>> print root.tag  #打印标题大标签

    collection

    >>> print root.attrib  #打印根部标签属性

    {'shelf': 'New Arrivals'}

    >>> for subnode in root:  #遍历根节点下的一级子节点及属性

    ...     print subnode

    ...     print subnode.tag

    ...     print subnode.attrib

    ...

    <Element 'movie' at 0x00000000022DD4E0>

    movie

    {'title': 'Enemy Behind'}

    <Element 'movie' at 0x00000000022DD6C0>

    movie

    {'title': 'Transformers'}

    <Element 'movie' at 0x00000000022DD810>

    movie

    {'title': 'Trigun'}

    <Element 'movie' at 0x00000000022DD9C0>

    movie

    {'title': 'Ishtar'}

    >>> root[0].getchildren() #获得第一个根节点的子节点

    [<Element 'type' at 0x00000000022DD510>, <Element 'format'

    >, <Element 'year' at 0x00000000022DD5A0>, <Element 'rating

    D0>, <Element 'stars' at 0x00000000022DD600>, <Element 'des

    00022DD660>]

    >>> root[0].getchildren()[1] #获得第一个根节点的第二个子节点

    <Element 'format' at 0x00000000022DD570>

    >>> root[0].getchildren()[1].text #获得第一个根节点的第二个子节点的文本

    'DVD'

    小练习:获得所有根节点下的description

    >>> for element in root:

    ...     print element.getchildren()[-1].text

    ...

    Talk about a US-Japan war

    A schientific fiction

    Vash the Stampede!

    Viewable boredom

     1. 继续遍历xml文件

    >>> print root #拿到根节点

    <Element 'collection' at 0x00000000022DD480>

    >>> print root[0] #拿到根节点第一个

    <Element 'movie' at 0x00000000022DD4E0>

    >>> print root[0][0] #拿到根节点第一个的第一个元素

    <Element 'type' at 0x00000000022DD510>

    >>> print root[0][0].tag #拿到根节点第一个的第一个元素的标签

    type

    >>> print root[0][0].text #拿到根节点第一个的第一个元素的文本

    War, Thriller

    >>> print root[0][0].attrib #拿到根节点第一个的第一个元素的属性

    {}

    注意:修改xml后再读取属性需要重新获取tree.root,否则内存中仍保留未修改前解析的tree结构,读取结果也是未修改前的。

    修改xml增加一个属性值后再读取:

    >>> tree = ET.ElementTree(file='e:\movie2.xml')

    >>> root = tree.getroot()

    >>> print root[0]

    <Element 'movie' at 0x00000000022DDBA0>

    >>> print root[0][0]

    <Element 'type' at 0x00000000022DDC00>

    >>> print root[0][0].attrib

    {'a': 'qiqiqiqi'}

    >>> print root[0][0].text

    War, Thriller

    >>> print root[0][0].tag

    Type

     

    2.继续遍历xml文件

    >>> tree = ET.ElementTree(file='e:\movie2.xml')

    >>> for element in tree.iter():

    ...     print element  #获取根节点下的所有元素及标签名

    ...     print element.tag

    ...

    <Element 'collection' at 0x00000000022DD960>

    collection

    <Element 'movie' at 0x00000000022DD900>

    movie

    <Element 'type' at 0x00000000022DD8A0>

    type

    <Element 'format' at 0x00000000022DD870>

    format

    <Element 'year' at 0x00000000022DD6C0>

    year

    <Element 'rating' at 0x00000000022DD7E0>

    rating

    <Element 'stars' at 0x00000000022DD7B0>

    stars

    <Element 'description' at 0x00000000022DD750>

    description

    <Element 'movie' at 0x00000000022DD6F0>

    movie

    <Element 'type' at 0x00000000022DD690>

    type

    <Element 'format' at 0x00000000022DD4E0>

    format

    <Element 'year' at 0x00000000022DD660>

    year

    <Element 'rating' at 0x00000000022DD600>

    rating

    <Element 'stars' at 0x00000000022DD5D0>

    stars

    <Element 'description' at 0x00000000022DD5A0>

    description

    <Element 'movie' at 0x00000000022DD570>

    movie

    <Element 'type' at 0x00000000022DD510>

    type

    <Element 'format' at 0x00000000022DD4B0>

    format

    <Element 'episodes' at 0x00000000022DD420>

    episodes

    <Element 'rating' at 0x00000000022DD3C0>

    rating

    <Element 'stars' at 0x00000000022E0210>

    stars

    <Element 'description' at 0x00000000022E0240>

    description

    <Element 'movie' at 0x00000000022E0270>

    movie

    <Element 'type' at 0x00000000022E02A0>

    type

    <Element 'format' at 0x00000000022E02D0>

    format

    <Element 'rating' at 0x00000000022E0300>

    rating

    <Element 'stars' at 0x00000000022E0330>

    stars

    <Element 'description' at 0x00000000022E0360>

    Description

    小练习:统计一下这个root下有多少个movie?

    自己的方法:

    >>> tree = ET.ElementTree(file='e:\movie2.xml')

    >>> result = 0

    >>> for element in tree.iter():

    ...     if element.tag == "movie":

    ...         result+=1

    ...

    >>> print result

    4

    小练习:统计一下这个root下全部的标签个数?

    >>> count=0

    >>> for element in tree.iter():

    ...     count+=1

    ...

    >>> print count

    28

    老师的方法:读文件

    直接用iterfind:

    >>> count=0

    >>> for element in tree.iterfind('movie'):

    ...     count+=1

    ...

    >>> print count

    4

    用tag找标签名:

    >>> for element in tree.iter(tag = 'movie'):

    ...     print element

    ...

    <Element 'movie' at 0x00000000022E0450>

    <Element 'movie' at 0x00000000022E0660>

    <Element 'movie' at 0x00000000022E07B0>

    <Element 'movie' at 0x00000000022E0960>

    小练习:判断是否存在1989的值

    >>> for element in tree.iter():

    ...     if element.text == "1989":

    ...         print "find it!"

    ...         break

    ... else:

    ...     print "not exist!"

    ...

    find it!

    3. 继续遍历xml文件

    删除:

    print tree.write(sys.stdout) #将 xml 文件的内容写到屏幕上
    tree.write("d:\movies.xml") #将变更的 xml 文件写入到文件中

    >>> del root[0]
    >>> del root[0]
    >>> del root[0]
    >>> import sys
    >>> print tree.write(sys.stdout)
    <collection shelf="New Arrivals">
    <movie title="Ishtar">
       <type>Comedy</type>
       <format>VHS</format>
       <rating>PG</rating>
       <stars>2</stars>
       <description>Viewable boredom</description>
    </movie>
    </collection>None
    >>>
    >>> tree.write("e:\movies.xml")

    删除只是删除内存中的,在写入回去才会删除

    4. 创建xml文件

    >>> import sys

    >>> import xml.etree.cElementTree as ET

    >>> a = ET.Element('elem')  #生成一个节点 elem,没有文本节点

    >>> c = ET.SubnElement(a,'child1') #生成一个字节点下的子节点 child1

    >>> c = ET.SubElement(a,'child1') #在子节点上添加文本节点

    >>> c.text = 'qiqiqi'

    >>> d = ET.SubElement(a,'child2') #生成一个字节点下的子节点 child2

    >>> b = ET.Element('elem_b') #生成一个节点 elem_b,没有文本节点

    >>> root = ET.Element('root') #生成一个节点 root

    >>> root.extend((a,b))  #把a,b两个值同级写入根节点

    >>> tree = ET.ElementTree(root) #生成节点树

    >>> root[0].set('foo','bar') #设定第一个子元素的属性 foo,值为 bar

    >>> print tree.write(sys.stdout) #打印节点树

    <root><elem foo="bar"><child1>qiqiqi</child1><child2 /></elem><elem_b /

    one

    >>> tree.write(sys.stdout) #将 xml 文件内容写到屏幕上

    <root><elem foo="bar"><child1>qiqiqi</child1><child2 /></elem><elem_b /

    tree.write("d:\test.xml") #将 xml 文件内容写入到文本文件中

    练习:自己创建一个xml的文件,里面包含数据的ip和端口信息,以及用户名和密码

    同学的答案:

    #encoding=utf-8
    import sys
    try:
        import xml.etree.cElementTree as ET
    except ImportError:
        import xml.etree.ElementTree as ET
    a = ET.Element('ipinfo') 
    c = ET.SubElement(a, 'ipadress') 
    c.text = "10.20.178.90 


    d = ET.SubElement(a, 'port') 
    d.text ="8080"
    a2 = ET.Element('userinfo')
    c2= ET.SubElement(a2, 'username')
    c2.text = "administrator"
    d2= ET.SubElement(a2, 'password')
    d2.text ="000000"
    root = ET.Element('root') 
    root.extend((a, a2)) #将a和a2加到root节点下
    tree = ET.ElementTree(root) #生成节点树
    root[0].set('conf', 'sql') 
    print tree.write(sys.stdout) 
    tree.write("E:\test2.xml") 

    面试题:有一个数组,里面满足一个条件,就是从里面随机取出三个值,之和为0,那么输出这数组中的三个数  eg:0,0,0,1,-1,2,-1

    import random
    a=[0,0,0,1,1,-1,-1,2]
    count = 0
    while 1:
        count+=1
        random.shuffle(a)  #把a的顺序打乱
        if a[0]+a[1]+a[2] == 0: #每次取前3个  (防止取出来的是同一个元素)
            print a[0],a[1],a[2]
            break
    print count

    同学的方法:

    list = [0,0,0,1,-1,2,-1]
    while True:
        slice = random.sample(list, 3)
        if sum(slice)==0:
            print slice
            break

    平时还得多训练多做题

    5. 边读边解析xml文件

    #coding=utf-8
    import sys
    try:
    import xml.etree.cElementTree as ET
    except ImportError:
    import xml.etree.ElementTree as ET
    tree = ET.parse("d:\movies.xml")
    count = 0
    for elem in tree.iter(tag='movie'): #遍历树中的 movie 节点
    print elem.tag
    if elem[0].text == 'War, Thriller':
    count += 1
    print count
    #以下代码实现了边读文件边解析的作用,节省了内存
    count = 0
    for event, elem in ET.iterparse("d:\movies.xml"): #遍历所有 xml 文件中的标签
    #print elem.tag
    if event == 'end': #检测“闭合的” (end)事件,标签关闭
    if elem.tag == 'type' and elem.text == 'War, Thriller': #标签为 type,且文本内容为
    War, Thriller ,则 count+1
    count += 1
    elem.clear() #清除元素内容,不清除则整个儿树也会在内存中,没有起到节省内存的作用。
    print count
    #事件
    #start 在元素打开时触发。数据和元素的子元素仍不可用。
    # end 在元素关闭时触发。所有元素的子节点,包括文本节点,现在都是可用的。
    #close 在解析完成后触发。

    官方文档:

    https://docs.python.org/2/library/xml.etree.elementtree.html 

    http://www.cnblogs.com/hongfei/p/python-xml-sax.html

  • 相关阅读:
    javaSE基础(六)--IO流
    javaSE基础(五)--JDBC
    javaSE基础(四)--Map集合
    javaSE基础(三)--List集合
    javaSE基础(二)
    javaSE基础(一)
    eclipse快捷键大全
    mybatis学习-基础
    工厂模式
    GC日志和jvm内存的分代
  • 原文地址:https://www.cnblogs.com/qingqing-919/p/8342900.html
Copyright © 2011-2022 走看看