當你須要解析和處理 XML 的時候,Python 表現出了它 「batteries included」 的一面。 標準庫 中大量可用的模塊和工具足以應對 Python 或者是 XML 的新手。node
ElementTree 生來就是爲了處理 XML ,它在 Python 標準庫中有兩種實現。一種是純 Python 實現例如 xml.etree.ElementTree ,另一種是速度快一點的 xml.etree.cElementTree 。python
從 Python 3.3 開始,ElementTree 模塊會自動尋找可用的 C 庫來加快速度。因此只須要 importxml.etree.ElementTreeapp
XML 是一種分級的數據形式,因此最天然的表示方法是將它表示爲一棵樹。ET 有兩個對象來實現這個目的 - ElementTree 將整個 XML 解析爲一棵樹, Element 將單個結點解析爲樹。若是是整個文檔級別的操做(好比說讀,寫,找到一些有趣的元素)一般用 ElementTree 。單個 XML 元素和它的子元素一般用 Element 。dom
eg:ide
xm.xml
工具
<data> <country name="Liechtenstein"> <rank updated="yes">2</rank> <year>2023</year> <gdppc>141100</gdppc> <neighbor direction="E" name="Austria" /> <neighbor direction="W" name="Switzerland" /> </country> <country name="Singapore"></country> </data>
加載而且解析這個 XML :xml
from xml.etree import ElementTree as et tree = et.parse('xm') root = tree.getroot() #獲取xml文件的根節點 print(root) print(root.tag) <Element 'data' at 0x00A28750> data
# 遍歷XML文檔的第二層 for child in root: # 第二層節點的標籤名稱和標籤屬性 print(child.tag, child.attrib) # 遍歷XML文檔的第三層 for i in child: # 第二層節點的標籤名稱和內容 print(i.tag,i.text)
咱們能夠用一個簡單的遞歸獲取 XML 中的任何元素。然而,由於這個操做比較廣泛,ET 提供了一些有用的工具來簡化操做對象
遍歷全部的元素,而後檢驗有沒有你想要的。ET 可讓這個過程更便捷。 iter 方法接受一個標籤名字,而後只遍歷那些有指定標籤的元素:遞歸
from xml.etree import ElementTree as ET ############ 解析方式一 ############ """ # 打開文件,讀取XML內容 str_xml = open('xo.xml', 'r').read() # 將字符串解析成xml特殊對象,root代指xml文件的根節點 root = ET.XML(str_xml) """ ############ 解析方式二 ############ # 直接解析xml文件 tree = ET.parse("xo.xml") # 獲取xml文件的根節點 root = tree.getroot() ### 操做 # 頂層標籤 print(root.tag) # 遍歷XML中全部的year節點 for node in root.iter('year'): # 節點的標籤名稱和內容 print(node.tag, node.text)
修改節點內容內存
因爲修改的節點時,均是在內存中進行,其不會影響文件中的內容。因此,若是想要修改,則須要從新將內存中的內容寫到文件。
from xml.etree import ElementTree as ET ############ 解析方式一 ############# 打開文件,讀取XML內容 str_xml = open('xm.xml', 'r').read() # 將字符串解析成xml特殊對象,root代指xml文件的根節點 root = ET.XML(str_xml) ############ 操做 ############ print(root.tag) # 循環全部的year節點 for node in root.iter('year'): # 將year節點中的內容自增一 new_year = int(node.text) + 1 node.text = str(new_year) # 設置屬性 node.set('name', 'alex') node.set('age', '18') # 刪除屬性 del node.attrib['name'] ############ 保存文件 ############ tree = ET.ElementTree(root) tree.write("newnew.xml", encoding='utf-8')
from xml.etree import ElementTree as ET ############ 解析方式二 ############# 直接解析xml文件 tree = ET.parse("xo.xml") # 獲取xml文件的根節點 root = tree.getroot() ############ 操做 ############# 頂層標籤print(root.tag) # 循環全部的year節點 for node in root.iter('year'): # 將year節點中的內容自增一 new_year = int(node.text) + 1 node.text = str(new_year) # 設置屬性 node.set('name', 'alex') node.set('age', '18') # 刪除屬性 del node.attrib['name'] ############ 保存文件 ############ tree.write("newnew.xml", encoding='utf-8')
刪除節點
# 頂層標籤 print(root.tag) # 遍歷data下的全部country節點 for country in root.findall('country'): # 獲取每個country節點下rank節點的內容 rank = int(country.find('rank').text) if rank > 50: # 刪除指定country節點 root.remove(country) ############ 保存文件 ############ 仍是前面那兩種方式
建立XML文檔
from xml.etree import ElementTree as ET # 建立根節點 root = ET.Element("famliy") # 建立節點大兒子 son1 = ET.Element('son', {'name': '兒1'}) # 建立小兒子 son2 = ET.Element('son', {"name": '兒2'}) # 在大兒子中建立兩個孫子 grandson1 = ET.Element('grandson', {'name': '兒11'}) grandson2 = ET.Element('grandson', {'name': '兒12'}) son1.append(grandson1) son1.append(grandson2) # 把兒子添加到根節點中 root.append(son1) root.append(son1) tree = ET.ElementTree(root) tree.write('oooo.xml',encoding='utf-8', short_empty_elements=False)
建立方式二:
from xml.etree import ElementTree as ET # 建立根節點 root = ET.Element("famliy") # 建立大兒子 son1 = root.makeelement('son', {'name': '兒1'}) # 建立小兒子 son2 = root.makeelement('son', {"name": '兒2'}) # 在大兒子中建立兩個孫子 grandson1 = son1.makeelement('grandson', {'name': '兒11'}) grandson2 = son1.makeelement('grandson', {'name': '兒12'}) son1.append(grandson1) son1.append(grandson2) # 把兒子添加到根節點中 root.append(son1) root.append(son1) tree = ET.ElementTree(root) tree.write('oooo.xml',encoding='utf-8', short_empty_elements=False)
方式三:
from xml.etree import ElementTree as ET # 建立根節點 root = ET.Element("famliy") # 建立節點大兒子 son1 = ET.SubElement(root, "son", attrib={'name': '兒1'}) # 建立小兒子 son2 = ET.SubElement(root, "son", attrib={"name": "兒2"}) # 在大兒子中建立一個孫子 grandson1 = ET.SubElement(son1, "age", attrib={'name': '兒11'}) grandson1.text = '孫子' et = ET.ElementTree(root) #生成文檔對象 et.write("test.xml", encoding="utf-8", xml_declaration=True, short_empty_elements=False)
因爲原生保存的XML時默認無縮進,若是想要設置縮進的話, 須要修改保存方式:
from xml.etree import ElementTree as ET from xml.dom import minidom def prettify(elem): """將節點轉換成字符串,並添加縮進。 """ rough_string = ET.tostring(elem, 'utf-8') reparsed = minidom.parseString(rough_string) return reparsed.toprettyxml(indent="\t") 按上面方式建立文檔內容 raw_str = prettify(root) f = open("xxxoo.xml",'w',encoding='utf-8') f.write(raw_str) f.close()