python网络编程学习笔记(八):XML生成与解析(DOM、ElementTree)


Posted in Python onJune 09, 2014

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

<?xml version="1.0" encoding="utf-8"?>
<info>
   <intro>Book message</intro>
    <list id='001'>
        <head>bookone</head>
        <name>python check</name>
        <number>001</number>
        <page>200</page>
    </list>
    <list id='002'>
        <head>booktwo</head>
        <name>python learn</name>
        <number>002</number>
        <page>300</page>
    </list>
</info>

(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

运行结果为:

[<DOM Text node "u'\n   '">, <DOM Element: intro at 0x124ef58>, <DOM Text node "u'\n    '">, <DOM Element: list at 0x1254058>, <DOM Text node "u'\n\n    '">, <DOM Element: list at 0x1254418>, <DOM Text node "u'\n\n'">]

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方法。
当要获取节点值时,如<head>bookone</head>中的bookone用text方法。
当要获取节点名时,用tag方法。

Python 相关文章推荐
用Python编写一个简单的FUSE文件系统的教程
Apr 02 Python
使用Python设置tmpfs来加速项目的教程
Apr 17 Python
python写入中英文字符串到文件的方法
May 06 Python
Python中http请求方法库汇总
Jan 06 Python
python实现的二叉树定义与遍历算法实例
Jun 30 Python
用python实现将数组元素按从小到大的顺序排列方法
Jul 02 Python
python django model联合主键的例子
Aug 06 Python
Python实现的微信红包提醒功能示例
Aug 22 Python
Django--权限Permissions的例子
Aug 28 Python
Python JSON编解码方式原理详解
Jan 20 Python
查看keras的默认backend实现方式
Jun 19 Python
python中spy++的使用超详细教程
Jan 29 Python
python网络编程学习笔记(七):HTML和XHTML解析(HTMLParser、BeautifulSoup)
Jun 09 #Python
python网络编程学习笔记(六):Web客户端访问
Jun 09 #Python
python网络编程学习笔记(五):socket的一些补充
Jun 09 #Python
python网络编程学习笔记(四):域名系统
Jun 09 #Python
python网络编程学习笔记(三):socket网络服务器
Jun 09 #Python
python网络编程学习笔记(二):socket建立网络客户端
Jun 09 #Python
python网络编程学习笔记(一)
Jun 09 #Python
You might like
提高php运行速度的一些小技巧分享
2012/07/03 PHP
php实现可运算的验证码
2015/11/10 PHP
Javascript中eval函数的使用方法与示例
2007/04/09 Javascript
jQuery 使用手册(七)
2009/09/23 Javascript
javascript 特性检测并非浏览器检测
2010/01/15 Javascript
js中访问html中iframe的文档对象的代码[IE6,IE7,IE8,FF]
2011/01/08 Javascript
新发现一个骗链接的方法(js读取cookies)
2012/01/11 Javascript
10款非常有用的 Ajax 插件分享
2012/03/14 Javascript
Javascript对象属性方法汇总
2013/11/21 Javascript
jQuery 复合选择器应用的几个例子
2014/09/11 Javascript
Bootstrap基础学习
2015/06/16 Javascript
前端jquery部分很精彩
2016/05/03 Javascript
AngularJS表格样式简单设置方法示例
2017/03/03 Javascript
Popup弹出框添加数据实现方法
2017/10/27 Javascript
JavaScript键盘事件常见用法实例分析
2019/01/03 Javascript
JS拖动选择table里的单元格完整实例【基于jQuery】
2019/05/28 jQuery
Vue实现固定定位图标滑动隐藏效果
2019/05/30 Javascript
解决VUE项目localhost端口服务器拒绝连接,只能用127.0.0.1的问题
2020/08/14 Javascript
[00:50]2014DOTA2国际邀请赛 NEWBEE战队回顾
2014/08/01 DOTA
Python发送Email方法实例
2014/08/21 Python
python多重继承实例
2014/10/11 Python
在Python中操作时间之tzset()方法的使用教程
2015/05/22 Python
python 默认参数问题的陷阱
2016/02/29 Python
python制作爬虫爬取京东商品评论教程
2016/12/16 Python
python pandas库中DataFrame对行和列的操作实例讲解
2018/06/09 Python
Django跨域请求问题的解决方法示例
2018/06/16 Python
使用Py2Exe for Python3创建自己的exe程序示例
2018/10/31 Python
使用memory_profiler监测python代码运行时内存消耗方法
2018/12/03 Python
Python3打包exe代码2种方法实例解析
2020/02/17 Python
Python GUI编程学习笔记之tkinter界面布局显示详解
2020/03/30 Python
如何利用Python动态模拟太阳系运转
2020/09/04 Python
CSS3 transform的skew属性值图文详解
2014/07/21 HTML / CSS
周年庆典主持词
2014/04/02 职场文书
优秀乡村医生事迹材料
2014/05/28 职场文书
学雷锋宣传标语
2014/06/25 职场文书
2015年世界环境日活动总结
2015/02/11 职场文书