Python 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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/usr/bin/env python
# -*- coding:utf-8 -*-

from xml.dom import minidom


#第一部分:xml解析

xml_str = \
' \
<school> \
<class id="c1" name="cl_name"> \
<student id="0001" name="student_1"> \
<subject id="math" score="98"/> \
<subject id="english" score="89"/> \
</student> \
<student id="0002" name="student_2"> \
<subject id="math" score="87"/> \
<subject id="english" score="99"/> \
</student> \
</class> \
<class id="c2" name="c2_name"> \
<student id="0003" name="student_3"> \
<subject id="math" score="88"/> \
<subject id="english" score="97"/> \
</student> \
<student id="0004" name="student_4"> \
<subject id="math" score="89"/> \
<subject id="english" score="92"/> \
</student> \
</class> \
<teachers> \
<teacher id="tec_001">tec_name1</teacher> \
<teacher id="tec_002">tec_name2</teacher> \
<teacher id="tec_003">tec_name3</teacher> \
</teachers> \
</school> \
'


#把string类型的xml转换成xml对象,如果是从文件中读取的xml,可以用minidom.parse方法
dom = minidom.parseString(xml_str)
#首先获得xml的根节点
rootdoc = dom.documentElement

classNodes = rootdoc.getElementsByTagName('class')

#当取得一个节点(此时节点的对象是Element)的时候,可以通过两种方式来访问
#方法一:通过下标的形式访问
if classNodes.length > 0:
#获得第一个节点对象
firstClass = classNodes[0];
#获得节点的属性值
class_id = firstClass.getAttribute('id')
class_name = firstClass.getAttribute('name')
print '方法一:class_id=%s, class_name=%s' % (class_id, class_name)
#方法二:通过for循环来便利所有取得的节点
for cls in classNodes:
class_id = cls.getAttribute('id')
class_name = cls.getAttribute('name')
print '方法二:class_id=%s, class_name=%s' % (class_id, class_name)

#获得一个节点下面的子节点
class_children = classNodes[0].getElementsByTagName('student')
print class_children.length #具体的实现取得属性和上面实例相同

#在xml的解析器中可以进行跨节点访问。
#比如说:如果我们要获得teacher节点,按照以前的方法我们先要获得teachers节点,然后再得到其子节点
#而现在我们不需要获得父亲节点,直接就可以取得teacher的节点
teacher_nodes = rootdoc.getElementsByTagName('teacher') #此方法是获得这个xml中所有名为teacher的节点
for tec in teacher_nodes:
teacher_id = tec.getAttribute('id')
#获得节点text的值,这个个人感觉有些怪异,按照正常的思路想的方法是tec.data,但是这个方法不行,只能运用下面的方法获得
teacher_text = tec.firstChild.data
print 'teacher: teacher_id=%s, teacher_name=%s' % (teacher_id, teacher_text)
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
    
#第二部分 生成xml

#首先获得一个Dom的实现
dom_impl = minidom.getDOMImplementation();
#创建一个具体的xml 西面函数接受三个参数(namespaceurl, 根节点,doctype)
dom = dom_impl.createDocument(None, 'application', None)
#获得xml文档的根节点
root = dom.documentElement
#给根节点添加属性
root.setAttribute('id', 'xml_id')
root.setAttribute('name', 'xml_name')
#创建注释
comment = dom.createComment("This is a comment")
dom.appendChild(comment)
dom.insertBefore(comment, root);
#创建子节点
propertyElement = dom.createElement('property')
root.appendChild(propertyElement)
fieldElement = dom.createElement('filed')
fieldElement.setAttribute('id', 'filed_id')
fieldElement.setAttribute('name', 'filed_name')
#给节点设置Text的值
fieldElementText = dom.createTextNode("File Text")
fieldElement.appendChild(fieldElementText)

propertyElement.appendChild(fieldElement)

#打印刚刚生成的xml
print dom.toxml('utf-8')

#如果你需要把xml文件写入到文件中
import codecs
ff = open('temp.xml', 'w')
#设置一个写入文件的控制器
writer = codecs.lookup('utf-8')[3](ff)
dom.writexml(writer, addindent='\t', newl='\n', encoding='utf-8')
writer.flush()
writer.close()


#下面是最终生成xml的格式
#<?xml version="1.0" encoding="utf-8"?>
#<!--This is a comment-->
#<application id="xml_id" name="xml_name">
# <property>
# <filed id="filed_id" name="filed_name">
# File Text
# </filed>
# </property>
#</application>
文章目录
,