Python使用ElementTree處理XML縮進和換行

一、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')

參考文獻

  1. 官方文檔 https://docs.python.org/zh-cn/3.7/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element
  2. 菜鳥教程 https://www.runoob.com/python/python-xml.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章