xml.dom篇
dom是document object model的简称,xml 文档的高级树型表示。该模型并非只针对 python,而是一种普通xml 模型。python 的 dom 包是基于 sax 构建的,并且包括在 python 2.0 的标准 xml 支持里。
一、xml.dom的简单介绍
1、主要方法:
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节点的xml表示的文本:
doc = minidom.parse(filename)
doc.toxml('utf-8')
访问元素属性:
node.attributes[id]
a.name #就是上面的 id
a.value #属性的值
2、举例说明
例1:文件名:book.xml
复制代码 代码如下:
book message
bookone
python check
001
200
booktwo
python learn
002
300
(1)创建dom对象
复制代码 代码如下:
import xml.dom.minidom
dom1=xml.dom.minidom.parse('book.xml')
(2)获取根字节
root=dom1.documentelement #这里得到的是根节点
print root.nodename,',',root.nodevalue,',',root.nodetype
返回结果为:
info , none , 1
其中:
info是指根节点的名称root.nodename
none是指根节点的值root.nodevalue
1是指根节点的类型root.nodetype,更多节点类型如下表:
nodetype
named constant
1
element_node
2
attribute_node
3
text_node
4
cdata_section_node
5
entity_reference_node
6
entity_node
7
processing_instruction_node
8
comment_node
9
document_node
10
document_type_node
11
document_fragment_node
12
notation_node
(3)子元素、子节点的访问
a、返回root子节点列表
复制代码 代码如下:
import xml.dom.minidom
dom1=xml.dom.minidom.parse('book.xml')
root=dom1.documentelement
#print root.nodename,',',root.nodevalue,',',root.nodetype
print root.childnodes
运行结果为:
[, , , , , , ]
b、获取xml节点值,如返回根节点下第二个子节点intro的值和名字,添加下面一句
复制代码 代码如下:
print root.childnodes[1].nodename,root.childnodes[1].nodevalue
运行结果为:
intro none
c、访问第一个节点
复制代码 代码如下:
print root.firstchild.nodename
运行结果为:
#text
d、获取已经知道的元素名字的值,如要获取intro后的book message可以使用下面的方法:
复制代码 代码如下:
import xml.dom.minidom
dom1=xml.dom.minidom.parse('book.xml')
root=dom1.documentelement
#print root.nodename,',',root.nodevalue,',',root.nodetype
node= root.getelementsbytagname('intro')[0]
for node in node.childnodes:
if node.nodetype in (node.text_node,node.cdata_section_node):
print node.data
这种方法的不足之处是需要对类型进行判断,使用起来不是很方便。运行结果是:
book message
二、xml解析
对上面的xml进行解析
方法1 代码如下:
复制代码 代码如下:
#@小五义 http://www.cnblogs.com/xiaowuyi
#xml 解析import xml.dom.minidom
dom1=xml.dom.minidom.parse('book.xml')
root=dom1.documentelement
book={}
booknode=root.getelementsbytagname('list')
for booklist in booknode:
print '='*20
print 'id:'+booklist.getattribute('id')
for nodelist in booklist.childnodes:
if nodelist.nodetype ==1:
print nodelist.nodename+':',
for node in nodelist.childnodes:
print node.data
运行结果为:
====================
id:001
head: bookone
name: python check
number: 001
page: 200
====================
id:002
head: booktwo
name: python learn
number: 002
page: 300
方法二:
代码:
复制代码 代码如下:
#@小五义 http://www.cnblogs.com/xiaowuyi
#xml 解析 import xml.dom.minidom
dom1=xml.dom.minidom.parse('book.xml')
root=dom1.documentelement
book={}
booknode=root.getelementsbytagname('list')
for booklist in booknode:
print '='*20
print 'id:'+booklist.getattribute('id')
print 'head:'+booklist.getelementsbytagname('head')[0].childnodes[0].nodevalue.strip()
print 'name:'+booklist.getelementsbytagname('name')[0].childnodes[0].nodevalue.strip()
print 'number:'+booklist.getelementsbytagname('number')[0].childnodes[0].nodevalue.strip()
print 'page:'+booklist.getelementsbytagname('page')[0].childnodes[0].nodevalue.strip()
运行结果与方法一一样。比较上面的两个方法,方法一根据xml的树结构进行了多次循环,可读性上不及方法二,方法直接对每一个节点进行操作,更加清晰。为了更加方法程序的调用,可以使用一个list加一个字典进行存储,具体见方法3:
复制代码 代码如下:
#@小五义 http://www.cnblogs.com/xiaowuyi
#xml 解析
import xml.dom.minidom
dom1=xml.dom.minidom.parse('book.xml')
root=dom1.documentelement
book=[]
booknode=root.getelementsbytagname('list')
for booklist in booknode:
bookdict={}
bookdict['id']=booklist.getattribute('id')
bookdict['head']=booklist.getelementsbytagname('head')[0].childnodes[0].nodevalue.strip()
bookdict['name']=booklist.getelementsbytagname('name')[0].childnodes[0].nodevalue.strip()
bookdict['number']=booklist.getelementsbytagname('number')[0].childnodes[0].nodevalue.strip()
bookdict['page']=booklist.getelementsbytagname('page')[0].childnodes[0].nodevalue.strip()
book.append(bookdict)
print book
运行结果为:
[{'head': u'bookone', 'page': u'200', 'number': u'001', 'id': u'001', 'name': u'python check'}, {'head': u'booktwo', 'page': u'300', 'number': u'002', 'id': u'002', 'name': u'python learn'}]
该列表里包含了两个字典。
三、建立xml文件
这里用方法三得到的结果,建立一个xml文件。
复制代码 代码如下:
# -*- coding: cp936 -*-
#@小五义 http://www.cnblogs.com/xiaowuyi
#xml 创建 import xml.dom
def create_element(doc,tag,attr):
#创建一个元素节点
elementnode=doc.createelement(tag)
#创建一个文本节点
textnode=doc.createtextnode(attr)
#将文本节点作为元素节点的子节点
elementnode.appendchild(textnode)
return elementnode
dom1=xml.dom.getdomimplementation()#创建文档对象,文档对象用于创建各种节点。
doc=dom1.createdocument(none,info,none)
top_element = doc.documentelement# 得到根节点
books=[{'head': u'bookone', 'page': u'200', 'number': u'001', 'id': u'001', 'name': u'python check'}, {'head': u'booktwo', 'page': u'300', 'number': u'002', 'id': u'002', 'name': u'python learn'}]
for book in books:
snode=doc.createelement('list')
snode.setattribute('id',str(book['id']))
headnode=create_element(doc,'head',book['head'])
namenode=create_element(doc,'name',book['name'])
numbernode=create_element(doc,'number',book['number'])
pagenode=create_element(doc,'page',book['page'])
snode.appendchild(headnode)
snode.appendchild(namenode)
snode.appendchild(pagenode)
top_element.appendchild(snode)# 将遍历的节点添加到根节点下
xmlfile=open('bookdate.xml','w')
doc.writexml(xmlfile,addindent=' '*4, newl='\n', encoding='utf-8')
xmlfile.close()
运行后生成bookdate.xml文件,该文件与book.xml一样。
xml.etree.elementtree篇
依然使用例1的例子,对xml进行解析分析。
1、加载xml
方法一:直接加载文件
复制代码 代码如下:
import xml.etree.elementtree
root=xml.etree.elementtree.parse('book.xml')
方法二:加载指定字符串
复制代码 代码如下:
import xml.etree.elementtree
root = xml.etree.elementtree.fromstring(xmltext)这里xmltext是指定的字符串。
2、获取节点
方法一 利用getiterator方法得到指定节点
book_node=root.getiterator(list)
方法二 利用getchildren方法得到子节点,如例1中,要得到list下面子节点head的值:
复制代码 代码如下:
#@小五义 http://www.cnblogs.com/xiaowuyiimport xml.etree.elementtree
root=xml.etree.elementtree.parse('book.xml')
book_node=root.getiterator(list)
for node in book_node:
book_node_child=node.getchildren()[0]
print book_node_child.tag+':'+book_node_child.text
运行结果为:
head:bookone
head:booktwo
方法三 使用find和findall方法
find方法找到指定的第一个节点:
复制代码 代码如下:
# -*- coding: cp936 -*-
#@小五义
import xml.etree.elementtree
root=xml.etree.elementtree.parse('book.xml')
book_find=root.find('list')
for note in book_find:
print note.tag+':'+note.text
运行结果:
head:bookone
name:python check
number:001
page:200
findall方法将找到指定的所有节点:
复制代码 代码如下:
# -*- coding: cp936 -*-
#@小五义
import xml.etree.elementtree
root=xml.etree.elementtree.parse('book.xml')
book=root.findall('list')
for book_list in book:
for note in book_list:
print note.tag+':'+note.text
运行结果:
head:bookone
name:python check
number:001
page:200
head:booktwo
name:python learn
number:002
page:300
3、对book.xml进行解析的实例
复制代码 代码如下:
# -*- coding: cp936 -*-
#@小五义
import xml.etree.elementtree
root=xml.etree.elementtree.parse('book.xml')
book=root.findall('list')
for book_list in book:
print '='*20
if book_list.attrib.has_key('id'):
print id:+book_list.attrib['id']
for note in book_list:
print note.tag+':'+note.text
print '='*20
运行结果为:
====================
id:001
head:bookone
name:python check
number:001
page:200
====================
id:002
head:booktwo
name:python learn
number:002
page:300
====================
注意:
当要获取属性值时,如list id='001',用attrib方法。
当要获取节点值时,如
bookone中的bookone用text方法。
当要获取节点名时,用tag方法。