python网络编程学习笔记(八):XML生成与解析(DOM、ElementTree)
2018-10-15 17:36
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.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 代码如下:
复制代码 代码如下:
#@小五义
#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
方法二:
代码:
复制代码 代码如下:
#@小五义
#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:
复制代码 代码如下:
#@小五义
#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: ubookone, page: u200, number: u001, id: u001, name: upython check}, {head: ubooktwo, page: u300, number: u002, id: u002, name: upython learn}]
该列表里包含了两个字典。
三、建立XML文件
这里用方法三得到的结果,建立一个xml文件。
复制代码 代码如下:
# -*- coding: cp936 -*-
#@小五义
#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: ubookone, page: u200, number: u001, id: u001, name: upython check}, {head: ubooktwo, page: u300, number: u002, id: u002, name: upython 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的值:
复制代码 代码如下:
#@小五义
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网络编程学习笔记(八):XML生成与解析(DOM、ElementTree)
文章链接:http://soscw.com/index.php/essay/18821.html