我有一个内存中的python XML ElementTree,它看起来像
<A>
<B>..</B>
<C>..</C>
<D>..</D>
</A>
我通过
将ElementTree序列化为xmlxmlstr = minidom.parseString(ET.tostring(root)).toprettyxml(" ")
每次调用上面的tostring()方法时,内部节点B,C,D的顺序都会改变。如何确保序列化遵循确定性顺序?
答案 0 :(得分:1)
我意识到这里有很多答案,但是
minidom.parseString(ET.tostring(root)).toprettyxml(" ")
实际上是一种非常可怕的打印XML文件的方式。
它涉及使用ET进行解析,序列化,然后再次解析并使用完全不同的XML库进行序列化。这是愚蠢和浪费,如果minidom搞砸了我也不会感到惊讶。
如果已安装,请切换到lxml and use its built-in pretty-printing function。
如果由于某些原因而无法使用xml.etree.ElementTree,则可以使用简单的递归函数来就地对树进行美化:
# xmlhelpers.py
# taken from http://effbot.org/zone/element-lib.htm#prettyprint
def indent(elem, level=0):
i = "\n" + level*" "
if len(elem):
if not elem.text or not elem.text.strip():
elem.text = i + " "
if not elem.tail or not elem.tail.strip():
elem.tail = i
for elem in elem:
indent(elem, level+1)
if not elem.tail or not elem.tail.strip():
elem.tail = i
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i
用法很简单:
import xml.etree.ElementTree as ET
from xmlhelpers import indent
root = ET.fromstring("<A><B>..</B><C>..</C><D>..</D></A>")
indent(root)
print( ET.tostring(root) )
这打印出一个很好的缩进版本:
b'<A>\n <B>..</B>\n <C>..</C>\n <D>..</D>\n</A>\n'
话虽如此,从不使用“tostring”将XML树写入文件。
始终使用XML库提供的功能编写XML文件。
tree = ET.ElementTree(root) # only necessary if you don't already have a tree
tree.write(filename, encoding="UTF-8")