python——XML解析(ElementTree vs SAX vs DOM)

python有三种方法解析XML:SAXDOM,以及ElementTree,介绍如下

1.SAX (simple API for XML )

      pyhton 标准库包含SAX解析器,SAX是一种典型的极为快速的工具,在解析XML时,不会占用大量内存

但是这是基于回调机制的,因此在某些数据中,它会调用某些方法进行传递。这意味着必须为数据指定句柄,

以维持自己的状态,这是非常困难的。

2.DOM(Document Object Model)

      与SAX比较,DOM典型的缺点是比较慢,消耗更多的内存,因为DOM会将整个XML数读入内存中,并为树

中的第一个节点建立一个对象。使用DOM的好处是你不需要对状态进行追踪,因为每一个节点都知道谁是它的

父节点,谁是子节点。但是DOM用起来有些麻烦。

   常用的DOM操作方法:  

1

2

3

4

5

6

7

8

9

10

minidom.parse(filename)   #加载读取XML文件

doc.documentElement      #获取XML文档对象

node.getAttribute(AttributeName)  # 获取XML节点属性值

node.getElementsByTagName(TagName)  #获取XML节点对象集合

node.childNodes    #返回子节点列表

node.childNodes[index].nodeValue #获取XML节点值

node.firstChild  #访问第一个节点。等价于pagexml.childNodes[0]

Node.attributes["id"]

a.name #就是上面的 "id"

a.value #属性的值

3. ElementTree

    ElementTree就像一个轻量级的DOM,具有方便友好的API。代码可用性好,速度快,消耗内存少,这里主要

介绍DOM和ElementTree。

代码举例

1. 下面是一个转载的例子,使用ElementTree:

test.xml如下:

1

2

3

4

5

6

7

8

9

10

11

<span style="font-size:13px;"><?xml version="1.0" encoding="utf-8"?>

 <root>

  <person age="18">

    <name>hzj</name>

    <sex>man</sex>

 </person>

  <person age="19" des="hello">

     <name>kiki</name>

     <sex>female</sex>

 </person>

</root></span>

1)加载xml文件

   加载XML文件共有2种方法,一是加载指定字符串,二是加载指定文件

2)获取element的方法

 a) 通过getiterator

 b) 过 getchildren

 c) find方法

 d) findall方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

#-*- coding:utf-8 -*-

 from xml.etree import ElementTree

 def print_node(node):

     '''打印结点基本信息'''

     print "=============================================="

     print "node.attrib:%s" % node.attrib

     if node.attrib.has_key("age") > 0 :

        print "node.attrib['age']:%s" % node.attrib['age']

     print "node.tag:%s" % node.tag

     print "node.text:%s" % node.text

 def read_xml(text):

     '''读xml文件'''

     # 加载XML文件(2种方法,一是加载指定字符串,二是加载指定文件)    

     # root = ElementTree.parse(r"D:/test.xml")

     root = ElementTree.fromstring(text)

     # 获取element的方法

     # 1 通过getiterator 

     lst_node = root.getiterator("person")

     for node in lst_node:

         print_node(node)

     # 2通过 getchildren

     lst_node_child = lst_node[0].getchildren()[0]

     print_node(lst_node_child)

     # 3 .find方法

     node_find = root.find('person')

     print_node(node_find)

     #4. findall方法

     node_findall = root.findall("person/name")[1]

     print_node(node_findall)

 if __name__ == '__main__':

      read_xml(open("test.xml").read())

想想为什么?不明白,请看下面:

1

2

3

4

5

6

7

8

9

10

11

12

13

#encoding=utf-8

from xml.etree import ElementTree as ET

#要找出所有人的年龄

per=ET.parse('test.xml')

p=per.findall('/person')

for in p:

    print x.attrib

print

for oneper in p:  #找出person节点

   for child in oneper.getchildren(): #找出person节点的子节点

        print child.tag,':',child.text

   print 'age:',oneper.get('age')

   print '############'

结果如下:

1

2

3

4

5

6

7

8

9

10

{'age': '18'}

{'age': '19', 'des': 'hello'}

name : hzj

sex : man

age: 18

############

name : kiki

sex : female

age: 19

############

2. 另外一个转载的例子,使用DOM:

XML文件:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

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

<users>

    <user id="1000001">

        <username>Admin</username>

        <email>admin@</email>

        <age>23</age>

        <sex>男</sex>

    </user>

    <user id="1000002">

        <username>Admin2</username>

        <email>admin2@</email>

        <age>22</age>

        <sex>男</sex>

    </user>

    <user id="1000003">

        <username>Admin3</username>

        <email>admin3@</email>

        <age>27</age>

        <sex>男</sex>

    </user>

    <user id="1000004">

        <username>Admin4</username>

        <email>admin4@</email>

        <age>25</age>

        <sex>女</sex>

    </user>

    <user id="1000005">

        <username>Admin5</username>

        <email>admin5@</email>

        <age>20</age>

        <sex>男</sex>

    </user>

    <user id="1000006">

        <username>Admin6</username>

        <email>admin6@</email>

        <age>23</age>

        <sex>女</sex>

    </user>

</users>

示例代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

# -*- coding:utf-8 -*-

"""

* User: lhj588

* Date: 11-11-9

* Time: 13:20

* Desc:

"""

from  xml.dom import  minidom

def get_attrvalue(node, attrname):

     return node.getAttribute(attrname) if node else ''

def get_nodevalue(node, index = 0):

    return node.childNodes[index].nodeValue if node else ''

def get_xmlnode(node,name):

    return node.getElementsByTagName(name) if node else []

def xml_to_string(filename='user.xml'):

    doc = minidom.parse(filename)

    return doc.toxml('UTF-8')

def get_xml_data(filename='user.xml'):

    doc = minidom.parse(filename)

    root = doc.documentElement

    user_nodes = get_xmlnode(root,'user')

    user_list=[]

    for node in user_nodes:

        user_id = get_attrvalue(node,'id')

        node_name = get_xmlnode(node,'username')

        node_email = get_xmlnode(node,'email')

        node_age = get_xmlnode(node,'age')

        node_sex = get_xmlnode(node,'sex')

        user_name =get_nodevalue(node_name[0]).encode('utf-8','ignore')

        user_email = get_nodevalue(node_email[0]).encode('utf-8','ignore')

        user_age = int(get_nodevalue(node_age[0]))

        user_sex = get_nodevalue(node_sex[0]).encode('utf-8','ignore')

        user = {}

        user['id'] , user['username'] , user['email'] , user['age'] , user['sex'= (

            int(user_id), user_name , user_email , user_age , user_sex

        )

        user_list.append(user)

    return user_list

def test_xmltostring():

    print xml_to_string()

def test_laod_xml():

    user_list = get_xml_data()

    for user in user_list :

        #print user['sex']

        print '-----------------------------------------------------'

        if user:

            user_str='编   号:%dn用户名:%sn性   别:%sn年   龄:%sn邮   箱:%sn ' % (int(user['id']) , user['username'], user['sex'] , user['age'] , user['email'])

            print user_str

            print '====================================================='

if __name__ == "__main__":

    test_xmltostring()

    test_laod_xml()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

科技颠覆未来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值