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中如下圖所示:
整個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, indent, newline, 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"。
參考文章:
https://blog.csdn.net/shinobiii/article/details/8253976