轉載請注明:@小五義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 , 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/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
運行結果:
head:bookone
name:python check
number:001
page:200
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
運行結果:
head:bookone
name:python check
number:001
page:200
head:booktwo
name:python learn
number:002
page:300
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方法。