Python解析XML文件
文本記錄如何利用python解析XML文件:
首先,XML示例文件如下所示(test.xml):
<?xml version="1.0" encoding="ISO-8859-1"?> <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>
1. 導入解析XML文件的模塊:xml.etree.ElementTree
import xml.etree.ElementTree as ET
注:解析XML方法很多,這里只介紹其一,xml.etree.ElementTree是按照XML文件的格式,將其看作樹來解析。
2. 解析步驟:
(1) 實例化Element對象:
tree = ET.ElementTree()
可見直接調用ET模塊的ElementTree方法返回一個Element對象,該對象指向XML樹的根節點。
現在來介紹Element對象的幾個常用屬性:
- tag:獲取該元素節點的標簽。 比如根節點的標簽是<data>,那么tree.tag返回的就是字符串data
- attrib:獲取噶元素節點的屬性字典,沒有屬性就返回空字典。 比如元素標簽為country的節點的屬性為name='Liechetenstein'那么返回的就是字典{name : 'Liechetenstein'}
- text:若該元素內沒有再嵌套,那么返回的就是該元素的內容(類型視元素內容的類型而定)。 比如year元素調用text后返回的是2008
(2)載入XML文件:
上一步僅僅是創建了XML樹的對象,其中沒有內容,現在就要載入xml文件來使這顆XML樹具有具體含義。
tree.parse("test.xml")
Element對象調用parse方法將xml文件載入進來,其中parse方法的參數便是xml文件的路徑。
這樣,這顆xml樹就要具體含義了,其含義與載入的xml文件含義同。
(3) 現在開始操作xml樹(操作xml文件的內容):
1. 載入xml文件后的樹是指向根節點的:
print(tree.tag)
輸出:
2. 可以使用len()函數查看該節點的子節點個數:
print(len(tree))
3. 可以按下標索引子節點:
比如tree[0].tag的結果是country,意思是根節點的第一個子節點的標簽是country
4. Element對象的findall()方法:
tree.findall('country')
該方法接受參數為檢索的元素標簽(String類型),返回的是一個列表(列表中的每個值都是Element對象,即檢索到的元素):
比如:
children = tree.findall('country') # 調用方法findall,會在tree的子節點中尋找以country為標簽的元素,將找到的元素放入列表中,最后返回這個列表 for child in children: # for循環遍歷這個列表中的每個元素,循環體print語句輸出每個元素的長度 print(len(child))
運行結果如下所示:(可以對比test.xml文件來理解輸出)
5. 也可以使用find()函數:
child1 = tree[0] # child1鎖定到tree的第一個孩子結點 print(child1.find('year').text) # child.find('year')指向該節點的year元素,然后.text返回該元素的內容
運行結果:(果然不出所料)
一次性操作xml文件示范代碼:
childtag = tree[0].tag # 根目錄的孩子結點的標簽 children = tree.findall(childtag) # 返回所有根目錄孩子結點元素的列表 for child in children: # 遍歷該列表 for i in range(len(child)): # 獲取每個孩子結點元素的長度,然后遍歷輸出所有內容 print(child[i].tag + ':' + str(child[i].text)) print()
運行結果如下:
(4)寫XML文件
import xml.etree.ElementTree as ET root = ET.Element('data') # 創建根節點調用方法Element # 創建子節點用方法SubElement,其中第一個參數為他的父節點,第二個參數為該節點的標簽 # 第三個參數為該節點的屬性(可選) student = ET.SubElement(root,'student',sex = 'boy') # 創建子節點,其父節點為student,用text來設置該節點的內容 ET.SubElement(student,'name').text = 'Tony' ET.SubElement(student,'age').text = '22' # 與student節點同級的節點 student = ET.SubElement(root,'student',sex = 'girl') ET.SubElement(student,'name').text = 'Tina' ET.SubElement(student,'age').text = '21' # xml的寫工作完成后調用ElementTree方法創建一顆xml樹 # 其參數為Element類型,即這顆樹的根 tree = ET.ElementTree(root) # ElementTree對象調用write方法,將數寫入到xml文件中 # 第一個參數為文件路徑,第二個參為編碼格式(記得寫) tree.write('test.xml',encoding='utf-8')
運行結果如下:
---------------------------------------------------------- 參考API ---------------------------------------------------------------
1.函數
1.xml.etree.ElementTree.Comment(text=None):注釋元素工廠,這個工廠函數創建一個特殊的元素,將被序列化為XML注釋標准的序列化器。注釋字符串可以是bytestring或Unicode字符串,文本是包含注釋字符串的字符串,返回表示注釋的元素實例。
注意:XMLParser忽略了輸入中的注釋,而不是為它們創建注釋對象。如果ElementTree使用其中一個元素方法插入到樹中,它只會包含注釋節點。
2.xml.etree.ElementTree.dump(elem):把元素樹或元素結構寫入sys.stdout。這個函數只用於調試。
3.xml.etree.ElementTree.fromstring(text):從字符串常量解析XML,XML()方法解析的方式也一樣,它們返回的都是一個Element實例。
4.xml.etree.ElementTree.iselement(element):檢查對手是否是有效的element對象,如果是element對象返回true,否則返回false.
5.xml.etree.ElementTree.iterparse(source, events=None, parser=None):在元素樹中逐步解析XML,並且報告用戶的情況。資源是文件名或包含xml數據的文件對象。一系列的事件需要被報告,支持事件的字符串有 “start”, “end”, “start-ns” and “end-ns”,如果忽略事件,則只報告“end”事件。解析器是一個可選的解析器實例。如果沒有給出,則使用標准的XMLParser解析器。解析器必須是XMLParser的子類,並且只能使用默認的TreeBuilder作為目標。使用iterparse()函數返回一個迭代器對象。
6.xml.etree.ElementTree.parse(source, parser=None):把XML文件解析成 element tree,資源是一個文件名或包含XML數據的文件對象,解析器是一個可選的解析器實例。如果沒有指定parser的參數值,默認使用的是XMLParser解析器。調用此函數返回ElementTree實例對象。
7.xml.etree.ElementTree.ProcessingInstruction(target, text=None):返回一個元素實例,表示一個處理指令。
8.xml.etree.ElementTree.register_namespace(prefix, uri):注冊命名空間前綴, registry是全局的,任何現有的前綴或名稱空間URI的映射都將被刪除。這個命名空間中的標簽和屬性將被給定的前綴給序列化。
9.xml.etree.ElementTree.SubElement(parent, tag, attrib={}, **extra):此函數是一個Subelement工廠,這個函數用於創建 element 實例,並將其添加到現有的 element 中。
10.xml.etree.ElementTree.tostring(element, encoding=”us-ascii”, method=”xml”, *, short_empty_elements=True): 轉化為字符串。
01.element:表示一個element實例
02. encoding:默認編碼是”us-ascii”
03.method:默認是”xml”,可以選擇“html”、“text”
11.xml.etree.ElementTree.tostringlist(element, encoding=”us-ascii”, method=”xml”, *, short_empty_elements=True):轉化成字符串列表。
12.xml.etree.ElementTree.XML(text, parser=None):
01.text :包含xml數據的字符串。
02.parser:解析器默認是XMLParser
03.返回的是一個Element實例
13.xml.etree.ElementTree.XMLID(text, parser=None):返回一個包含Element實例和字典的元組。
2.Element 對象
class xml.etree.ElementTree.Element(tag, attrib={}, **extra)
1.tag: 標簽
2.text: 去除標簽,獲得標簽中的內容。
3.attrib: 獲取標簽中的屬性和屬性值。
4.tail: 這個屬性可以用來保存與元素相關聯的附加數據。它的值通常是字符串,但可能是特定於應用程序的對象。
Element 對象的方法
1.clear():清除所有子元素和所有屬性,並將文本和尾部屬性設置為None。
2.get(attribute_name, default=None):通過指定屬性名獲取屬性值。
3.items():以鍵值對的形式返回元素屬性。
4.keys():以列表的方式返回元素名。
5.set(attribute_name,attribute_value):在某標簽中設置屬性和屬性值。
6.append(subelement):將元素子元素添加到元素的子元素內部列表的末尾。
7.extend(subelements):追加子元素。
8.find(match, namespaces=None):找到第一個匹配的子元素,match可以是標簽名或者path。返回Elememt實例或None。
9.findall(match, namespaces=None):找到所有匹配的子元素,返回的是一個元素列表。
10.findtext(match, default=None, namespaces=None):找到匹配第一個子元素的文本。返回的是匹配元素中的文本內容。
11.getchildren():Python3.2后使用 list(elem) 或 iteration.
12.getiterator(tag=None):Python3.2后使用 Element.iter()
13.iter(tag=None):以當前元素為根創建樹迭代器。迭代器遍歷這個元素和它下面的所有元素(深度優先級)。如果標簽不是None或’*’,那么只有標簽等於標簽的元素才會從迭代器返回。如果在迭代過程中修改樹結構,則結果是未定義的。
14.iterfind(match, namespaces=None):匹配滿足條件的子元素,返回元素。
15.itertext():創建一個文本迭代器。迭代器循環遍歷此元素和所有子元素,以文檔順序,並返回所有內部文本。
16.makeelement(tag, attrib):此方法使用SubElement()函數代替。
17.remove(subelement):刪除子元素。
3.ElementTree 對象
class xml.etree.ElementTree.ElementTree(element=None, file=None):
ElementTree是一個包裝器類,這個類表示一個完整的元素層次結構,並為標准XML的序列化添加了一些額外的支持。
1._setroot(element):替換根元素,原來的根元素中的內容會消失。
2.find(match, namespaces=None):從根元素開始匹配和 Element.find()作用一樣。
3.findall(match, namespaces=None):從根元素開始匹配和 Element.findall()作用一樣。
4.findtext(match, default=None, namespaces=None):從根元素開始匹配和 Element.findtext()作用一樣。
5.getiterator(tag=None):Python3.2后使用 ElementTree.iter() 代替。
6.iter(tag=None):迭代所有元素
7.iterfind(match, namespaces=None):從根元素開始匹配和 Element.iterfind()作用一樣。
8.parse(source, parser=None):解析xml文本,返回根元素。
9.write(file, encoding=”us-ascii”, xml_declaration=None, default_namespace=None, method=”xml”, *, short_empty_elements=True):寫出XML文本。