python网络编程学习笔记:XML生成与解析(DOM、ElementTree)
转载请注明:@小五义 http://www.cnblogs.com/xiaowuyi
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是指根节点的名称root.nodeName
None是指根节点的值root.nodeValue
1是指根节点的类型root.nodeType,更多节点类型如下表:
NodeType
Named Constant
ELEMENT_NODE
ATTRIBUTE_NODE
TEXT_NODE
CDATA_SECTION_NODE
ENTITY_REFERENCE_NODE
ENTITY_NODE
PROCESSING_INSTRUCTION_NODE
COMMENT_NODE
DOCUMENT_NODE
DOCUMENT_TYPE_NODE
DOCUMENT_FRAGMENT_NODE
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
运行结果为:
方法二:
代码:
# @小五义 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/xiaowuyi
import 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 -*- # @小五义 http://www.cnblogs.com/xiaowuyi 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
运行结果:
findall方法将找到指定的所有节点:
# -*- coding: cp936 -*- # @小五义 http://www.cnblogs.com/xiaowuyi 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
运行结果:
3、对book.xml进行解析的实例
# -*- coding: cp936 -*- # @小五义 http://www.cnblogs.com/xiaowuyi 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 , xml , DOM , ElementTree
作者: Leo_wl
出处: http://www.cnblogs.com/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息查看更多关于python网络编程学习笔记:XML生成与解析(DOM、ElementTree)的详细内容...