繁体   English   中英

如何以有序的xml节点方式序列化python ElementTree?

[英]How to serialize python ElementTree in ordered fashion of xml nodes?

我有一个内存中的python XML ElementTree,看起来像

<A>
  <B>..</B>
  <C>..</C>
  <D>..</D>
</A>

我将ElementTree序列化为xml

xmlstr = minidom.parseString(ET.tostring(root)).toprettyxml("  ")

每次调用上面的tostring()方法时,内部节点B,C,D的顺序都会改变。 如何确保序列化遵循确定性顺序?

我意识到这里有很多答案,但是

minidom.parseString(ET.tostring(root)).toprettyxml("  ")

实际上是一种非常可怕的打印XML文件的方式。

它涉及使用ET进行解析,序列化,然后再次解析并使用完全不同的XML库进行序列化。 这是愚蠢和浪费,如果minidom搞砸了我也不会感到惊讶。

如果安装了它,请切换到lxml并使用其内置的漂亮打印功能

如果您出于某种原因坚持使用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")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM