一、Python Xml介紹
1.1 解析方法
Python 有三種方法解析 XML。SAX,DOM,以及 ElementTree:
1.SAX (simple API for XML )
Python 標準庫包含 SAX 解析器,SAX 用事件驅動模型,通過在解析XML的過程中觸發一個個的事件並調用用戶定義的回調函數來處理XML文件。
2.DOM(Document Object Model)
將 XML 數據在內存中解析成一個樹,通過對樹的操作來操作XML。
3.ElementTree(元素樹)
ElementTree就像一個輕量級的DOM,具有方便友好的API。代碼可用性好,速度快,消耗內存少。
注:因DOM需要將XML數據映射到內存中的樹,一是比較慢,二是比較耗內存,而SAX流式讀取XML文件,比較快,佔用內存少,但需要用戶實現回調函數(handler)。
2.1 ElementTree介紹
xml.etree.ElementTree模塊實現了一個簡單高效的API,用於解析和創建XML數據。
警告 該xml.etree.ElementTree模塊對於惡意構建的數據是不安全的。如果您需要解析不可信或未經身份驗證的數據,請參見XML漏洞。
ElementTree對xml操作分爲兩級。
xml.etree.ElementTree.ElementTree(element=None, file=None)
。對於xml整個文件的操作(讀、寫等)是在這一級上。class xml.etree.ElementTree.Element(tag, attrib={}, **extra)
。對於xml元素的操作則在這一級上。
二、ElementTree基本使用
2.1 xml準備
這個是看菜鳥教程用的xml,這裏去掉了幾個換行
<collection shelf="New Arrivals">
<movie title="Enemy Behind"><type>War, Thriller</type><format>DVD</format>
<year>2003</year>
<rating>PG</rating>
<stars>10</stars>
<description>Talk about a US-Japan war</description>
</movie><movie title="Transformers">
<type>Anime, Science Fiction</type>
<format>DVD</format>
<year>1989</year>
<rating>R</rating>
<stars>8</stars>
<description>A schientific fiction</description>
</movie><movie title="Trigun">
<type>Anime, Action</type>
<format>DVD</format>
<episodes>4</episodes>
<rating>PG</rating>
<stars>10</stars>
<description>Vash the Stampede!</description>
</movie>
<movie title="Ishtar">
<type>Comedy</type>
<format>VHS</format>
<rating>PG</rating>
<stars>2</stars>
<description>Viewable boredom</description>
</movie>
</collection>
2.2 讀寫xml
import xml.etree.ElementTree as ET
# 從文件讀
tree = ET.parse('movies.xml')
root = tree.getroot()
# 從字符串讀
# root = ET.fromstring(country_data_as_string)
root 是 Element 類,有標籤和屬性字典root.tag,root.attrib
三、遍歷、換行和縮進
這個是處理換行和縮進的代碼
from xml.etree import ElementTree # 導入ElementTree模塊
def pretty_xml(element, indent, newline, level=0): # elemnt爲傳進來的Elment類,參數indent用於縮進,newline用於換行
if element: # 判斷element是否有子元素
if (element.text is None) or element.text.isspace(): # 如果element的text沒有內容
element.text = newline + indent * (level + 1)
else:
element.text = newline + indent * (level + 1) + element.text.strip() + newline + indent * (level + 1)
# else: # 此處兩行如果把註釋去掉,Element的text也會另起一行
# element.text = newline + indent * (level + 1) + element.text.strip() + newline + indent * level
temp = list(element) # 將element轉成list
for subelement in temp:
if temp.index(subelement) < (len(temp) - 1): # 如果不是list的最後一個元素,說明下一個行是同級別元素的起始,縮進應一致
subelement.tail = newline + indent * (level + 1)
else: # 如果是list的最後一個元素, 說明下一行是母元素的結束,縮進應該少一個
subelement.tail = newline + indent * level
pretty_xml(subelement, indent, newline, level=level + 1) # 對子元素進行遞歸操作
tree = ElementTree.parse('movies.xml') # 解析movies.xml這個文件
root = tree.getroot() # 得到根元素,Element類
pretty_xml(root, '\t', '\n') # 執行美化方法
tree.write('output.xml')
參考文獻
- 官方文檔 https://docs.python.org/zh-cn/3.7/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element
- 菜鳥教程 https://www.runoob.com/python/python-xml.html