python網(wǎng)絡(luò)編程學(xué)習(xí)筆記(八):XML生成與解析(DOM、ElementTree)
xml.dom篇
DOM是Document Object Model的簡(jiǎn)稱,XML 文檔的高級(jí)樹型表示。該模型并非只針對(duì) Python,而是一種普通XML 模型。Python 的 DOM 包是基于 SAX 構(gòu)建的,并且包括在 Python 2.0 的標(biāo)準(zhǔn) XML 支持里。
一、xml.dom的簡(jiǎn)單介紹
1、主要方法:
minidom.parse(filename):加載讀取XML文件
doc.documentElement:獲取XML文檔對(duì)象
node.getAttribute(AttributeName):獲取XML節(jié)點(diǎn)屬性值
node.getElementsByTagName(TagName):獲取XML節(jié)點(diǎn)對(duì)象集合
node.childNodes :返回子節(jié)點(diǎn)列表。
node.childNodes[index].nodeValue:獲取XML節(jié)點(diǎn)值
node.firstChild:訪問第一個(gè)節(jié)點(diǎn),等價(jià)于pagexml.childNodes[0]
返回Node節(jié)點(diǎn)的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)創(chuàng)建DOM對(duì)象
import xml.dom.minidom
dom1=xml.dom.minidom.parse('book.xml')
(2)獲取根字節(jié)
root=dom1.documentElement #這里得到的是根節(jié)點(diǎn)
print root.nodeName,',',root.nodeValue,',',root.nodeType
返回結(jié)果為:
info , None , 1
其中:
info是指根節(jié)點(diǎn)的名稱root.nodeName
None是指根節(jié)點(diǎn)的值root.nodeValue
1是指根節(jié)點(diǎn)的類型root.nodeType,更多節(jié)點(diǎn)類型如下表:
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)子元素、子節(jié)點(diǎn)的訪問
A、返回root子節(jié)點(diǎn)列表
import xml.dom.minidom
dom1=xml.dom.minidom.parse('book.xml')
root=dom1.documentElement
#print root.nodeName,',',root.nodeValue,',',root.nodeType
print root.childNodes
運(yùn)行結(jié)果為:
[<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節(jié)點(diǎn)值,如返回根節(jié)點(diǎn)下第二個(gè)子節(jié)點(diǎn)intro的值和名字,添加下面一句
print root.childNodes[1].nodeName,root.childNodes[1].nodeValue
運(yùn)行結(jié)果為:
intro None
C、訪問第一個(gè)節(jié)點(diǎn)
print root.firstChild.nodeName
運(yùn)行結(jié)果為:
#text
D、獲取已經(jīng)知道的元素名字的值,如要獲取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
這種方法的不足之處是需要對(duì)類型進(jìn)行判斷,使用起來不是很方便。運(yùn)行結(jié)果是:
Book message
二、xml解析
對(duì)上面的xml進(jìn)行解析
方法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
運(yùn)行結(jié)果為:
====================
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()
運(yùn)行結(jié)果與方法一一樣。比較上面的兩個(gè)方法,方法一根據(jù)xml的樹結(jié)構(gòu)進(jìn)行了多次循環(huán),可讀性上不及方法二,方法直接對(duì)每一個(gè)節(jié)點(diǎn)進(jìn)行操作,更加清晰。為了更加方法程序的調(diào)用,可以使用一個(gè)list加一個(gè)字典進(jìn)行存儲(chǔ),具體見方法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
運(yùn)行結(jié)果為:
[{'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'}]
該列表里包含了兩個(gè)字典。
三、建立XML文件
這里用方法三得到的結(jié)果,建立一個(gè)xml文件。
# -*- coding: cp936 -*-
#@小五義 http://www.cnblogs.com/xiaowuyi
#xml 創(chuàng)建
import xml.dom
def create_element(doc,tag,attr):
#創(chuàng)建一個(gè)元素節(jié)點(diǎn)
elementNode=doc.createElement(tag)
#創(chuàng)建一個(gè)文本節(jié)點(diǎn)
textNode=doc.createTextNode(attr)
#將文本節(jié)點(diǎn)作為元素節(jié)點(diǎn)的子節(jié)點(diǎn)
elementNode.appendChild(textNode)
return elementNode
dom1=xml.dom.getDOMImplementation()#創(chuàng)建文檔對(duì)象,文檔對(duì)象用于創(chuàng)建各種節(jié)點(diǎn)。
doc=dom1.createDocument(None,"info",None)
top_element = doc.documentElement# 得到根節(jié)點(diǎn)
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)# 將遍歷的節(jié)點(diǎn)添加到根節(jié)點(diǎn)下
xmlfile=open('bookdate.xml','w')
doc.writexml(xmlfile,addindent=' '*4, newl='\n', encoding='utf-8')
xmlfile.close()
運(yùn)行后生成bookdate.xml文件,該文件與book.xml一樣。
xml.etree.ElementTree篇
依然使用例1的例子,對(duì)xml進(jìn)行解析分析。
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、獲取節(jié)點(diǎn)
方法一 利用getiterator方法得到指定節(jié)點(diǎn)
book_node=root.getiterator("list")
方法二 利用getchildren方法得到子節(jié)點(diǎn),如例1中,要得到list下面子節(jié)點(diǎn)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
運(yùn)行結(jié)果為:
head:bookone
head:booktwo
方法三 使用find和findall方法
find方法找到指定的第一個(gè)節(jié)點(diǎn):
# -*- 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
運(yùn)行結(jié)果:
head:bookone
name:python check
number:001
page:200
findall方法將找到指定的所有節(jié)點(diǎn):
# -*- 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
運(yùn)行結(jié)果:
head:bookone
name:python check
number:001
page:200
head:booktwo
name:python learn
number:002
page:300
3、對(duì)book.xml進(jìn)行解析的實(shí)例
# -*- 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
運(yùn)行結(jié)果為:
====================
id:001
head:bookone
name:python check
number:001
page:200
====================
id:002
head:booktwo
name:python learn
number:002
page:300
====================
注意:
當(dāng)要獲取屬性值時(shí),如list id='001',用attrib方法。
當(dāng)要獲取節(jié)點(diǎn)值時(shí),如<head>bookone</head>中的bookone用text方法。
當(dāng)要獲取節(jié)點(diǎn)名時(shí),用tag方法。
- python標(biāo)準(zhǔn)庫ElementTree處理xml
- Python如何使用ElementTree解析xml
- Python使用ElementTree美化XML格式的操作
- 利用 Python ElementTree 生成 xml的實(shí)例
- Python3 xml.etree.ElementTree支持的XPath語法詳解
- Python利用ElementTree模塊處理XML的方法詳解
- python xml.etree.ElementTree遍歷xml所有節(jié)點(diǎn)實(shí)例詳解
- Python中使用ElementTree解析XML示例
- python通過ElementTree操作XML獲取結(jié)點(diǎn)讀取屬性美化XML
- python通過ElementTree操作XML
相關(guān)文章
Matplotlib自定義圖例(多張圖共享一個(gè)圖例)
最近再用Matplotlib繪圖,需要做兩個(gè)子圖都不需要設(shè)置圖例,圖例單獨(dú)用一個(gè)figure來顯示,本文就詳細(xì)的來介紹一下,感興趣的可以了解一下2023-08-08Pandas||過濾缺失數(shù)據(jù)||pd.dropna()函數(shù)的用法說明
這篇文章主要介紹了Pandas||過濾缺失數(shù)據(jù)||pd.dropna()函數(shù)的用法說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-05-05python GUI庫圖形界面開發(fā)之PyQt5表格控件QTableView詳細(xì)使用方法與實(shí)例
這篇文章主要介紹了python GUI庫圖形界面開發(fā)之PyQt5表格控件QTableView詳細(xì)使用方法與實(shí)例,需要的朋友可以參考下2020-03-03Python獲取好友地區(qū)分布及好友性別分布情況代碼詳解
利用Python + wxpy 可以快速的查詢自己好友的地區(qū)分布情況,以及好友的性別分布數(shù)量。還可以批量下載好友的頭像,拼接成大圖。感興趣的朋友跟隨小編一起看看吧2019-07-07對(duì)numpy下的軸交換transpose和swapaxes的示例解讀
今天小編就為大家分享一篇對(duì)numpy下的軸交換transpose和swapaxes的示例解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-06-06Python3之不使用第三方變量,實(shí)現(xiàn)交換兩個(gè)變量的值
今天小編就為大家分享一篇Python3之不使用第三方變量,實(shí)現(xiàn)交換兩個(gè)變量的值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-06-06Python利用pangu模塊實(shí)現(xiàn)文本格式化小工具
其實(shí)使用pangu做文本格式標(biāo)準(zhǔn)化的業(yè)務(wù)代碼在之前就實(shí)現(xiàn)了,主要能夠?qū)⒅形奈谋疚臋n中的文字、標(biāo)點(diǎn)符號(hào)等進(jìn)行標(biāo)準(zhǔn)化。但是為了方便起來我們這里使用了Qt5將其做成了一個(gè)可以操作的頁面應(yīng)用,需要的可以了解一下2022-10-10python學(xué)生信息管理系統(tǒng)(初級(jí)版)
這篇文章主要為大家詳細(xì)介紹了python學(xué)生信息管理系統(tǒng)的初級(jí)版本代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-10-10Python使用socket的UDP協(xié)議實(shí)現(xiàn)FTP文件服務(wù)功能
這篇文章主要介紹了Python使用socket的UDP協(xié)議實(shí)現(xiàn)FTP文件服務(wù),本示例主要是用Python的socket,使用UDP協(xié)議實(shí)現(xiàn)一個(gè)FTP服務(wù)端、FTP客戶端,用來實(shí)現(xiàn)文件的傳輸,需要的朋友可以參考下2023-10-10