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

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方法。

时间: 2016-06-09
Tags: python, xml, 解析

python网络编程学习笔记(八):XML生成与解析(DOM、ElementTree)_python的相关文章

python网络编程学习笔记(二):socket建立网络客户端_python

1.建立socket 建立socket对象需要搞清通信类型和协议家族.通信类型指明了用什么协议来传输数据.协议的例子包括IPv4.IPv6.IPX\SPX.AFP.对于internet通信,通信类型基本上都是AF_INET(和IPv4对应).协议家族一般表示TCP通信的SOCK_STREAM或者表示UDP通信的SOCK_DGRAM.因此对于TCP通信,建立一个socket连接的语句为:s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)对于UDP通

python网络编程学习笔记(一)_python

学习用书:<python 网络编程基础>作者John Goerzen 第一部分底层网络学习         Python提供了访问底层操作系统Socket接口的全部方法,需要的时候这些接口可以提供灵活而强有力的功能. (1)基本客户端操作         在<python 网络编程基础>一书中,作者列出了一个简单的Python客户端程序,具体如下: 复制代码 代码如下: import socket,sysport =70host=sys.argv[1] filename=sys.a

python网络编程学习笔记(六):Web客户端访问_python

6.1 最简单的爬虫 网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成.python的urllib\urllib2等模块很容易实现这一功能,下面的例子实现的是对baidu首页的下载.具体代码如下: 复制代码 代码如下: import urllib2page=urllib2.urlopen("http://www.baidu.com")print page.read() 6.2 提交表单数据 (1)用GET方法提交数据提交表单的GET方法是把表单数据

python网络编程学习笔记(三):socket网络服务器_python

1.TCP连接的建立方法 客户端在建立一个TCP连接时一般需要两步,而服务器的这个过程需要四步,具体见下面的比较. 步骤 TCP客户端 TCP服务器 第一步 建立socket对象  建立socket对象 第二步 调用connect()建立一个和服务器的连接 设置socket选项(可选) 第三步 无 绑定到一个端口(也可以是一个指定的网卡) 第四步 无 侦听连接 下面具体来讲这四步的建立方法: 第一步,建立socket对象:这里与客户端一样,依然是: s=socket.socket(socket.

python网络编程学习笔记(五):socket的一些补充_python

1.半开放socket 利用shutdown()函数使socket双向数据传输变为单向数据传输.shutdown()需要一个单独的参数,该参数表示了如何关闭socket.具体为:0表示禁止将来读:1 表示禁止将来写:2表示禁止将来读和写. 2.timeouts控制超时 调用socket的settimeout()函数,向其传递参数,表明超时时间设置.当访问一个socket,如果经过了参数设定的时间后,什么都没有发生,则会产生一个socket.timeout异常.例如:当程序运行后,会等待数据传入.

python网络编程学习笔记(10):webpy框架_python

django和webpy都是python的web开发框架.Django的主要目的是简便.快速的开发数据库驱动的网站.它强调代码复用,多个组件可以很方便的以"插件"形式服务于整个框架,Django有许多功能强大的第三方插件,你甚至可以很方便的开发出自己的工具包.这使得Django具有很强的可扩展性.它还强调快速开发和DRY(Do Not Repeat Yourself)原则.webpy小巧,简单,实用,可以快速的完成简单的web页面.这里根据webpy Cookbook简要的介绍一下we

Socket网络编程学习笔记(3):利用套接字助手类

在上一篇中已经介绍了利用Socket建立服务端和客户端进行通信,如果需要 的朋友可访问<Socket网络编程学习笔记(2):面向连接的Socket>.在本篇 中,将利用C#套接字的助手类来简化Socket编程,使得刚刚接触到网络编程的 朋友们更容易上手. 跟上篇一样,通过C#套接字的助手类来编程同样分 服务端和客户端. 一.服务端侦听模式 1.创建套接字与 IPEndPoint绑定,并设置为侦听模式. 1//创建IPEndPoint实例 2 IPEndPoint ipep = new IPEn

Socket网络编程学习笔记(1):常用方法介绍

虽然天天上博客园欣赏各位"大侠"的杰作,偶然回首,突然发 现自己已成"潜水者"久矣.本来对于自己有限的水平,有点不好意 思在此发贴,不过潜伏久了,才慢慢意识到老是通过浏览他人的文章虽然能够提 高自己能力,能够及时的获取新技术新思想,但却只能停留在他人的思想上.通 过学习,加上自己的想法,再写出来,让大家来指证错误,不仅能够巩固自己的 知识,也可以让一些跟我一样迷惘的朋友们不用再去走一些弯路,岂不是两全其 美,本着这样的想法,打算把自己平时的所学所想都写下来,欢迎各路

Python核心编程学习笔记之映射类型(上)

 根据核心编程第二版学习Python3.x的内容,可能有些欠缺,有些方法在3.x中已经不提供了,就暂时先略过了.等以后再对比2.x和3.x的区别,作下笔记吧 1.    Python中字典的定位: a)      字典是python中唯一的映射类型,通常被认为是可变的哈希表. b)     字典对象是可变的,能存储任意多个python对象. c)      字典是Python中最强大的数据类型之一 2.    字典(dict)和序列类型容器类(列表和元组)的区别: a)      存储和访问数据