python解析xml的方法總結

使用python開發時,由於python的開源生態圈非常的給力,對於實現同一個功能,往往在這方面的類庫非常多,而開發者也同樣面臨着如何選擇最佳的 類庫作爲輔助開發的工具。本文將記錄本人在使用python處理xml格式數據時測試過的類庫,有些類庫由於先天不足,無法支持一些特性,涉及的類庫或模 塊有xml(python自帶)、libxml2 、lxml 、xpath 。

附註:本文處理xml格式的數據的結構如下:

Python代碼

input_xml_string = """ 
                   1.0" url="http://***" />  <data version="2.0" url="http://***" /> item>  <data version="1.0" url="http://***" /> <data version="2.0" url="http://***" /> other> root> """ 

python自帶的xml處理模塊xml.dom.minidom 解析xml

可以使用該模塊提供的”getElementsByTagName“接口找到需要的節點,實例“get_tagname”如下:

Python代碼

import xml.dom.minidom def get_tagname(): doc = xml.dom.minidom.parseString(input_xml_string) for node in doc.getElementsByTagName("data"): print (node, node.tagName, node.getAttribute("version")) 

程序運行結果如下:

(, u'data', u'1.0')  
(, u'data', u'2.0')  
(, u'data', u'1.0')  
(, u'data', u'2.0')  

觀察上面的運行結果,”getElementsByTagName“接口查找名爲data的所有節點,有時候,程序需要完成的功能是只需要某個節點下面的 data節點,如other節點下的data節點。也許您馬上想到了,我們可以判斷data節點的父節點是否爲other來滿足功能,實例 “get_tagname_other”如下:

import xml.dom.minidom def get_tagname_other(): doc = xml.dom.minidom.parseString(input_xml_string) for node in doc.getElementsByTagName("data"): if node.parentNode.tagName == "other": print (node, node.tagName, node.getAttribute("version")) 

程序運行結果如下:

(, u'data', u'1.0')  
(, u'data', u'2.0')  

觀察上面的運行結果,恩,很好,問題是解決了,但是如果我想查找other節點下的data節點且屬性節點version等於1.0的那個data節點, 那麼就需要添加更多的策略來篩選出我們需要的數據,顯然這種方式不夠靈活,因此我們想到了使用xpath的方式去搜索我們需要的節點。實例 “get_xpath”如下:

import xml.etree.ElementTree from StringIO import StringIO file = StringIO(input_xml_string) def get_xpath(): doc = xml.etree.ElementTree.parse(file) for node in doc.findall("//item/data"): print (node, node.tag, (node.items())) 

程序運行結果如下:

(, 'data', [('url', 'http://***'), ('version', '1.0')])  
(, 'data', [('url', 'http://***'), ('version', '2.0')])  

觀察上面的運行結果,使用xpath的方式顯然改善了程序的可讀性,可依然沒有解決上面的問題,這是由於python自帶的xml模塊對xpath方式的支持先天不足,如果想同時滿足可讀性與功能的正確性,我們需要使用針對python的第三方xml處理類庫。

使用libxml2解析xml

libxml2是使用C語言開發的xml解析器,是一個基於MIT License的免費開源軟件,多種編程語言都有基於它的實現,如本文將會介紹的lxml模塊。實例“get_xpath_1”如下:

mport libxml2
def get_xpath_1():
doc = libxml2.parseFile("data.xml")#data.xml文件結構與上述的input_xml_string相同
for node in doc.xpathEval("//item/data[@version = '1.0']"):
print (node, node.name, (node.properties.name, node.properties.content))
doc.freeDoc()
程序運行結果如下:

(, 'data', ('version', '1.0'))  

觀察上面的運行結果,能夠滿足我們的需求,有點小不足“xpathEval()”接口不支持類似模板的用法,但不影響使用,由於libxml2採用C語言開發的,因此在使用API接口的方式上難免會有點“水土不服”(寫法或習慣性用法)

使用lxml解析xml

lxml是以上述介紹過的libxml2爲基礎採用python語言開發的,從使用層面上說比libxml2更適合python開發者(鄙人感受),且"xpath"接口支持類似模板的用法,實例“get_xpath_2”如下:

import lxml.etree def get_xpath_2(): doc = lxml.etree.parse(file) for node in doc.xpath("//item/data[@version = $name]", name = "1.0"): print (node, node.tag, (node.items())) 

程序運行結果如下:

(, 'data', [('version', '1.0'), ('url', 'http://***')])  

使用xpath模塊解析xml

xpath是python官方推薦的一個支持xpath等處理的模塊,是基於本文介紹過的python自帶xml處理模塊擴展而成,可以很好的結合使用,同時“find”接口也支持類似模板的用法,實例“get_xpath_3”如下:

Python代碼

import xpath def get_xpath_3(): doc = xml.dom.minidom.parseString(input_xml_string) for node in xpath.find("//item/data[@version = $name]", doc, name = "1.0"): print (node, node.tagName, node.getAttribute("version")) 

程序運行結果如下:

(, u'data', u'1.0')  

總結:

通過對這些類庫的實踐,我們已經瞭解了python在處理xml格式的數據時有各種各樣的選擇,並得知這些類庫各自擅長那些方面的處理和各種類庫的使用手法,可以根據實際需求選擇合適的類庫完成開發工作。

<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
閱讀(15787) | 評論(0) | 轉發(7) |
給主人留下些什麼吧!~~
評論熱議
發佈了194 篇原創文章 · 獲贊 57 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章