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列表去重的二种方法
Feb 14 Python
python检测远程服务器tcp端口的方法
Mar 14 Python
python中threading超线程用法实例分析
May 16 Python
python字符串中的单双引
Feb 16 Python
使用Python对SQLite数据库操作
Apr 06 Python
Python实现的爬虫功能代码
Jun 24 Python
python实现单向链表详解
Feb 08 Python
Python 中字符串拼接的多种方法
Jul 30 Python
python+splinter实现12306网站刷票并自动购票流程
Sep 25 Python
使用Python和Scribus创建一个RGB立方体的方法
Jul 17 Python
flask利用flask-wtf验证上传的文件的方法
Jan 17 Python
Python爬虫抓取指定网页图片代码实例
Jul 24 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 Socket配置以及实例的详细介绍
2013/06/13 PHP
php简单分页类实现方法
2015/02/26 PHP
ubuntu下配置nginx+php+mysql详解
2015/09/10 PHP
php验证身份证号码正确性的函数
2016/07/20 PHP
PHP实现实时生成并下载超大数据量的EXCEL文件详解
2017/10/23 PHP
基于jquery库的tab新形式使用
2012/11/16 Javascript
简单的ajax连接库分享(不用jquery的ajax)
2014/01/19 Javascript
jQuery 获取/设置/删除DOM元素的属性以a元素为例
2014/05/23 Javascript
Jquery日期选择datepicker插件用法实例分析
2015/06/08 Javascript
深入讲解AngularJS中的自定义指令的使用
2015/06/18 Javascript
jQuery实现带水平滑杆的焦点图动画插件
2016/03/08 Javascript
BootStrap selectpicker
2016/06/20 Javascript
jQuery操作cookie
2016/08/08 Javascript
javascript实现鼠标点击页面 移动DIV
2016/12/02 Javascript
Reactjs实现通用分页组件的实例代码
2017/01/19 Javascript
xmlplus组件设计系列之按钮(2)
2017/04/26 Javascript
Node.js对MongoDB数据库实现模糊查询的方法
2017/05/03 Javascript
在vue中多次调用同一个定义全局变量的实例
2018/09/25 Javascript
Promise扫盲贴
2019/06/24 Javascript
python获取一组数据里最大值max函数用法实例
2015/05/26 Python
Python通过属性手段实现只允许调用一次的示例讲解
2018/04/21 Python
Tensorflow 查看变量的值方法
2018/06/14 Python
python命令行工具Click快速掌握
2019/07/04 Python
在django中实现页面倒数几秒后自动跳转的例子
2019/08/16 Python
Pandas将列表(List)转换为数据框(Dataframe)
2020/04/24 Python
Python闭包装饰器使用方法汇总
2020/06/29 Python
教师年终个人自我评价
2013/10/04 职场文书
外国语学院毕业生自荐信
2013/10/28 职场文书
物业公司采购员岗位职责
2013/12/31 职场文书
老同学聚会感言
2014/02/23 职场文书
学雷锋献爱心活动总结
2015/05/11 职场文书
装修安全责任协议书
2016/03/22 职场文书
mysql 直接拷贝data 目录下文件还原数据的实现
2021/07/25 MySQL
详解使用内网穿透工具Ngrok代理本地服务
2022/03/31 Servers
直播实况, OMG破敌三路五十分钟大战神技局摩托车
2022/04/01 DOTA
Redis 异步机制
2022/05/15 Redis