1. 程式人生 > 程式設計 >Python使用ElementTree美化XML格式的操作

Python使用ElementTree美化XML格式的操作

Python中使用ElementTree可以很方便的處理XML,但是產生的XML檔案內容會合並在一行,難以看清楚。

如下格式:

<root><aa>aatext<cc>cctext</cc></aa><bb>bbtext<dd>ddtext<ee>eetext</ee></dd></bb></root>

使用minidom模組中的toprettyxml和writexml方法都有引數可以優化XML,但是有兩個問題:

a. 如果解析的XML已經是美化過的,那麼執行該方法會多出很多空行

b. 產生的結果會將text也獨立一行,如下:

<root> 
  <aa> 
    aatext 
  </aa> 
  <bb> 
    bbtext 
  </bb> 
</root> 

而我想產生如下結果:

<root> 
  <aa>aatext</aa> 
  <bb>bbtext</bb> 
</root> 

於是只能自己寫一個美化XML的方法。

我們首先研究一下ElementTree模組中的Element類,使用getroot方法返回的便是Element類。

該類中有四個屬性tag、attrib、text與tail,對應在XML中如下圖所示:

Python使用ElementTree美化XML格式的操作

整個XML就是一個Element,裡面嵌套了很多子Element。

Element可以使用for迴圈迭代。

通過在text和tail中增加換行和製表符,就可以實現美化XML的目的。

美化程式碼如下:

def prettyXml(element,indent,newline,level = 0): # elemnt為傳進來的Elment類,引數indent用於縮排,newline用於換行 
  if element: # 判斷element是否有子元素 
    if element.text == 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) # 將elemnt轉成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 
    prettyXml(subelement,level = level + 1) # 對子元素進行遞迴操作 
     
from xml.etree import ElementTree   #匯入ElementTree模組 
tree = ElementTree.parse('test.xml')  #解析test.xml這個檔案,該檔案內容如上文 
root = tree.getroot()         #得到根元素,Element類 
prettyXml(root,'\t','\n')      #執行美化方法 
ElementTree.dump(root)         #顯示出美化後的XML內容

輸出結果如下:

<root> 
  <aa> 
    aatext 
    <cc>cctext</cc> 
  </aa> 
  <bb> 
    bbtext 
    <dd> 
      ddtext 
      <ee>eetext</ee> 
    </dd> 
  </bb> 
</root> 

殘留問題點:

windows下的換行符是"\r\n",只需將prettyXml方法的第三個引數改為"\r\n",使用記事本開啟生成的XML大部分OK。

但是XML說明與根元素開始符之間不知如何插入"\r\n".

Python使用ElementTree美化XML格式的操作

補充知識:python-xml 模組-程式碼生成xml 文件

一、XML 模組

什麼是xml:可擴充套件的標記語言,標記翻譯為標籤,用標籤來組織資料的語言,也是一種語言可以用來自定義文件結構。相比json 使用場景更加廣泛,但是語法格式相比json 複雜很多

什麼時候使用json:前後臺互動資料時使用json

什麼時候使用xml:當需要自定義文件結構時使用xml,比如java中經常用xml來作為配置檔案,常見操作就是通過程式去讀取配置資訊,而修改增加刪除,一般是交給使用者來手動完成

標籤的叫發:node(節點)、elment(元素)、tag(標籤)

需求從conuntrys中獲取所有的國家名稱

==========================>countrys
<data>
  <country name="Liechtenstein">
    <rank updated="yes">2</rank>
    <year>2009</year>
    <gdppc>141100</gdppc>
    <neighbor direction="E" name="Austria" />
    <neighbor direction="W" name="Switzerland" />
  </country>
  <country name="Singapore">
    <rank updated="yes">5</rank>
    <year>2012</year>
    <gdppc>59900</gdppc>
    <neighbor direction="N" name="Malaysia" />
  </country>
  <country name="Panama">
    <rank updated="yes">69</rank>
    <year>2012</year>
    <gdppc>13600</gdppc>
    <neighbor direction="W" name="Costa Rica" />
    <neighbor direction="E" name="Colombia" />
  </country>
</data># 取別名可以用於簡化書寫
import xml.etree.ElementTree as ET
tree = ET.parse('countrys')
#獲取根標籤#第一種獲取標籤的方式
#全文查詢
iter() 
# 獲取迭代器 如果不指定引數 則迭代器迭代的是所有標籤
print(root.iter())
# 獲取迭代器 如果指定引數 則迭代器迭代的是所有名稱匹配的標籤
for e in root.iter("rank"):
  print(e)
 
#第二種獲取標籤的方式
#在當前標籤下(所有子級標籤)尋找第一個名稱匹配的標籤
print(root.find("rank")) #第一個名稱不匹配所以返回None#第三種獲取標籤的方式
#在當前標籤下(所有子級標籤)尋找所有名稱匹配的標籤
print(root.findall("rank")) #[]

練習:找到新加坡中year 這個標籤

#print(e.tag) #標籤名稱
#print(e.attrib) #屬性 字典型別
#print(e.text) #文字內容import xml.etree.ElementTree as ETtree = ET.parse("countrys")
# 獲取根標籤
root = tree.getroot()
for e in root.iter("country"):
  if e.attrib["name"] == "Singapore":
    y = e.find("year")
    print(y.text) #2012

在程式中修改文件內容:把所有year標籤的文字加1

import xml.etree.ElementTree as ETtree = ET.parse("countrys")
root = tree.getroot()
for e in root.iter("year"):
  e.text = str(int(e.text) + 1)
  
#做完修改後要將修改後的內容寫入檔案
tree.write('countrys')

把新加坡國家刪除:

import xml.etree.ElementTree as ETtree = ET.parse("countrys")
root = tree.getroot()for e in root.findall("country"):
  print(e)
  if e.attrib["name"] == "Singapore":
    #刪除時要通過被刪除的父級標籤來刪除
    root.remove(e)tree.write('countrys')

用程式將中國資訊寫入文件中:

import xml.etree.ElementTree as ETtree = ET.parse("countrys")
root = tree.getroot()
#新增時也需要將要新增的資料做成一個Element
c = ET.Element("country",{"name":"china"})# 在國家下有一堆子標籤
ranke = ET.Element("ranke",{"updated":"yes"})
c.append(ranke)year = ET.Element("year")
year.text = "2018"
c.append(year)#新增到root標籤中
root.append(c)
tree.write("countrys")

總結:一般不會通過程式 去修改 刪除 和新增

什麼時候應該使用XML格式:

當你需要自定文件結構時(XML最強大的地方就是結構)

前後臺互動不應該使用,前後臺互動應該使用JSON格式

程式碼生成XML文件

import xml.etree.ElementTree as ET# 建立根標籤
root = ET.Element("root")
root.text = "這是一個XML文件!"c = ET.Element("country",{"name":"china"})
root.append(c)tree = ET.ElementTree(root)
# 引數: 檔名稱 編碼方式 是否需要文件宣告
tree.write("new.xml",encoding="utf-8",xml_declaration=True)=========================>new.xml 內容為
<?xml version='1.0' encoding='utf-8'?>
<root>這是一個XML文件!<country name="china" /></root>

以上這篇Python使用ElementTree美化XML格式的操作就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。