Python 標准庫之 xml.etree.ElementTree


Python 標准庫之 xml.etree.ElementTree

Python中有多種xml處理API,常用的有xml.dom.*模塊、xml.sax.*模塊、xml.parser.expat模塊和xml.etree.ElementTree模塊(以下簡稱ET)。本文將主要介紹ET的使用,以及它的常用函數。其它模塊的簡介,請參照文獻[1]。
ET使用Element表示xml中的節點、文本、注釋等。其主要屬性如下:
tag:string對象,表示數據代表的種類,當為節點時為節點名稱。 text:string對象,表示element的內容。 attrib:dictionary對象,表示附有的屬性。 tail:string對象,表示element閉合之后的尾跡。 若干子元素(child elements)。
<tag attrib1=1>text</tag>tail
    1     3            2             4
PS: ET模塊對於那些惡意構造的數據並不是安全的,如果需要解析數據最好了一下xml的弱點[2]
 
一、導入ET
在Python標准庫中,ElementTree有兩種實現方式:一種是純Python的實現xml.etree.ElementTree,另一種是速度更快一點的xml.etree.cElementTree。如果不確定環境中是否有cElementTree,可以使用如下的方式導入:
try: import xml.etree.cElementTree as ET except ImportError: import xml.etree.ElementTree as ET
但從Python 3.3開始,會默認使用cElementTree來加快速度,但是之前的版本最好使用如上的代碼,以提高代碼的兼容性。
 
二、解析xml
假設我們現在有如下的xml
<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>
有兩種方式可以解析xml
1. 從文件中解析xml文件
>>> import xml.etree.cElementTree as ET >>> tree = ET.ElementTree(file='doc1.xml')     #載入數據
>>> root = tree.getroot()     #獲取根節點
<Element 'doc' at 0x11eb780>

 

2. 從內存字符串中解析xml
root = ET.fromstring(country_data_as_string)

 

其中第二種方式可以直接過去根節點。
 
三、數據的訪問
>>> for child in root: ... print child.tag, child.attrib ... country {'name': 'Liechtenstein'} country {'name': 'Singapore'} country {'name': 'Panama'}

或者直接使用索引尋找子節點:
>>> root[0][1].text '2008'
 
或者使用xpath方式進行遍歷,但其支持部分xpath方法,其支持的xpath請參照[4]
>>> root.findall("./country/neighbor") [<Element 'neighbor' at 0x14fa0f0>, <Element 'neighbor' at 0x14fa150>, <Element 'neighbor' at 0x14fa3f0>, <Element 'neighbor' at 0x14fa6c0>, <Element 'neighbor' at 0x14fa750>]

 

 
四、 處理xml流
如下的程序將從xml文件中一邊讀入xml一邊解析,並將在遇到標簽開始或標簽結束的時候返回相應的事件。
for event, elem in ET.iterparse(sys.argv[2]): if event == 'end': if elem.tag == 'location' and elem.text == 'Zimbabwe': count += 1 elem.clear() # discard the element
這個程序將在檢查到標簽結束的時候,對指定的標簽進行計數。最后的elem.clear()保證了,在解析的之后盡快的釋放內存。
 
五、Element對象
class xml.etree.ElementTree.Element(tag, attrib={}, **extra) tag:string 元素代表的數據種類。 text:string 元素的內容。 tail:string 元素的尾形。 attrib:dictionary 元素的屬性字典。 #針對屬性的操作 clear() 清空元素的后代、屬性、text和tail也設置為None。 get(key, default=None) 獲取key對應的屬性值,如該屬性不存在則返回default值。 items() 根據屬性字典返回一個列表,列表元素為(key, value)。 keys() 返回包含所有元素屬性鍵的列表。 set(key, value) 設置新的屬性鍵與值。 #針對后代的操作 append(subelement) 添加直系子元素。 extend(subelements) 增加一串元素對象作為子元素。#python2.7新特性 find(match) 尋找第一個匹配子元素,匹配對象可以為tag或path。 findall(match) 尋找所有匹配子元素,匹配對象可以為tag或path。 findtext(match) 尋找第一個匹配子元素,返回其text值。匹配對象可以為tag或path。 insert(index, element) 在指定位置插入子元素。 iter(tag=None) 生成遍歷當前元素所有后代或者給定tag的后代的迭代器。#python2.7新特性 iterfind(match) 根據tag或path查找所有的后代。 itertext() 遍歷所有后代並返回text值。 remove(subelement) 刪除子元素。

 

 
六、ElementTree對象
class xml.etree.ElementTree.ElementTree(element=None, file=None) element如果給定,則為新的ElementTree的根節點。 _setroot(element):用給定的element替換當前的根節點。慎用。 # 以下方法與Element類中同名方法近似,區別在於它們指定以根節點作為操作對象。 find(match) findall(match) findtext(match, default=None) iter(tag=None) iterfind(match) parse(source, parser=None) 裝載xml對象,source可以為文件名或文件類型對象 getroot() 獲取根節點 write(file, encoding="us-ascii", xml_declaration=None, default_namespace=None,method="xml") 

 

七、模塊方法-->用於生成xml文件
1. 創建一個特別的element,通過標准序列化使其代表了一個comment。comment可以為bytestring或unicode。
     ET.Comment(text=None)
2. 生成一個element tree,通過sys.stdout輸出,elem可以是元素樹或單個元素。這個方法最好只用於debug。 
     ET.dump(elem)
3. text是一個包含XML數據的字符串,與XML()方法類似,返回一個Element實例。 
     ET.fromstring(text)
4. 從字符串的序列對象中解析xml文檔。缺省parser為XMLParser,返回Element實例。V2.7中新加屬性 
     ET.fromstringlist(sequence, parser=None)
5. 檢查是否是一個element對象。 
     ET.iselement(element)
6. 將文件或包含xml數據的文件對象遞增解析為element tree,並且報告進度。events是一個匯報列表,如果忽略,將只有end事件會匯報出來。
     注意,iterparse()只會在看見開始標簽的">"符號時才會拋出start事件,因此屆時屬性是已經定義了,但是text和tail屬性在那時還沒有定義,同樣子元素也沒有定義,因此他們可能不能被顯示出來。如果你想要完整的元素,請查找end事件。
     ET.iterparse(source, events=None, parser=None)
7. 將一個文件或者字符串解析為element tree。 
     ET.parse(source, parser=None)
8. 這個方法會創建一個特別的element,該element被序列化為一個xml處理命令。 
     ET.ProcessingInstruction(target, text=None)
9. 注冊命名空間前綴。這個注冊是全局有效,任何已經給出的前綴或者命名空間uri的映射關系會被刪除。 V2.7新加屬性
     ET.register_namespace(prefix, uri)
10. 子元素工廠,創建一個Element實例並追加到已知的節點。 
     ET.SubElement(parent, tag, attrib={}, **extra)
11. 生成一個字符串來表示表示xml的element,包括所有子元素。element是Element實例,method為"xml", "html", "text"。 返回包含了xml數據的字符串。 
     ET.tostring(element, encoding="us-ascii", method="xml")
12. 生成一個字符串來表示表示xml的element,包括所有子元素。element是Element實例,method為"xml","html","text"。返回包含了xml數據的字符串列表。V2.7新添加屬性
     ET.tostringlist(element, encoding="us-ascii", method="xml")
13. 從一個字符串常量中解析出xml片段。返回Element實例。 
     ET.XML(text, parser=None)

 

14. 從字符串常量解析出xml片段,同時返回一個字典,用以映射element的id到其自身。 
     ET.XMLID(text, parser=None)


免責聲明!

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



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