python網絡編程學習筆記(8):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 , 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方法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM