天天看點

python解析xml---xml.etree.ElementTree

警告:

XML子產品對于錯誤或惡意構造的資料是不安全的。如果需要解析不受信任或未經身份驗證的資料,需要注意XML漏洞

xml.etree.ElementTree: ElementTree API, 一個簡單而輕量級的xml處理器。

1、該Element類型是一個靈活的容器對象,旨在将分層資料結構存儲在記憶體中。該類型可以描述為清單和字典之間的交叉。

2、每個元素都有許多與之關聯的屬性:

标簽、屬性(存儲在字典中)、文本字元串、許多子元素(存儲在Python序列中)

3、建立元素執行個體,請使用Element構造函數 和 SubElement()工廠函數。

XML樹和元素

XML是一種固有的分層資料格式,表示它的最自然的方式是使用樹。

ElementTree:将整個XML文檔表示為樹;

Element:表示此樹中的單個節點。

與整個文檔的互動(讀取和寫入檔案)通常在ElementTree關卡上完成。

與單個XML元素及其子元素的互動在該Element級别上完成。

從磁盤讀取xml檔案

舉例 test.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>
           
import xml.etree.ElementTree as ET

strXMLPath = 'test.xml'
tree = ET.parse(strXMLPath)    # xml.etree.ElementTree.ElementTree object
root = tree.getroot()          # Element 'data'
print root.tag, root.attrib    # 輸出:data {}
           

其中子節點,可以疊代而來:

for child in root:
    print child.tag, child.attrib

輸出:
country {'name': 'Liechtenstein'}
country {'name': 'Singapore'}
country {'name': 'Panama'}
           

子項是嵌套的,我們可以通過索引通路特定的子節點:

root[0][1].text

輸出: '2008'
           

查找元素

1、Element有一些有用的方法可以幫助遞歸疊代它下面的所有子樹(它的子節點,它們的子節點等)。例如, Element.iter():

for neighbor in root.iter('neighbor'):
    print neighbor.attrib

輸出:
{'direction': 'E', 'name': 'Austria'}
{'direction': 'W', 'name': 'Switzerland'}
{'direction': 'N', 'name': 'Malaysia'}
{'direction': 'W', 'name': 'Costa Rica'}
{'direction': 'E', 'name': 'Colombia'}
           

2、Element.findall()僅查找具有标記的元素,這些元素是目前元素的直接子元素。

Element.find()查找具有特定标記的第一個子項,并Element.text通路該元素的文本内容。 Element.get()通路元素的屬性:

for country in root.findall('country'):
    rank = country.find('rank').text
    name = country.get('name')
    print name, rank

輸出:
Liechtenstein 1
Singapore 4
Panama 68
           

修改XML

ElementTree提供了一種建構XML文檔并将其寫入檔案的簡單方法:ElementTree.write()。

Element.text
直接更改其字段
Element.set(key, value)方法
添加和修改屬性
Element.append()方法
增加新的子項
Element.remove(Element_del)
删除元素

例1:為每個國家/地區的排名+1,并為rank元素添加一個屬性 updated :

for rank in root.iter('rank'):
    new_rank = int(rank.text) + 1
    rank.text = str(new_rank)
    rank.set('updated', 'yes')

tree.write('output.xml')
           
python解析xml---xml.etree.ElementTree

例2:删除排名高于50的所有國家/地區:

for country in root.findall('country'):
    rank = int(country.find('rank').text)
    if rank > 50:
        root.remove(country)

tree.write('output.xml')
           
python解析xml---xml.etree.ElementTree

建構xml文檔

SubElement()函數:為給定元素建立新子元素

a = ET.Element('a')
b = ET.SubElement(a, 'b')
c = ET.SubElement(a, 'c')
d = ET.SubElement(c, 'd')
tree = ET.ElementTree(a)
tree.write('output.xml', encoding='utf-8')

輸出:
<a>
    <b/>
    <c>
        <d/>
    </c>
</a>