在python中通过xml.etree.ElementTree生成的xml文件中插入换行符

MK.*_*MK. 36 python xml

我在python中使用xml.etree.ElementTree创建了一个xml文件.然后我用

tree.write(filename, "UTF-8") 
Run Code Online (Sandbox Code Playgroud)

将文档写出到文件中.

但是当我使用文本编辑器(linux上的vi)打开文件名时,标签之间没有换行符.一切都是一条大路线

如何以"漂亮的打印"格式写出文档,以便在所有xml标记之间有新的行(并且希望缩进等)?

谢谢!

Eri*_*gel 55

我发现了一种避免新库和重新分析xml的新方法.您只需将根元素传递给此函数(请参阅下面的说明):

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
Run Code Online (Sandbox Code Playgroud)

xml.etree.ElementTree.Element实例上有一个名为" tail " 的属性.此属性可以在节点后设置字符串:

"<a>text</a>tail"
Run Code Online (Sandbox Code Playgroud)

我从2004年发现了一个链接,告诉我们使用这个"尾部"缩进元素的元素库函数.

例:

root = ET.fromstring("<fruits><fruit>banana</fruit><fruit>apple</fruit></fruits>""")
tree = ET.ElementTree(root)

indent(root)
# writing xml
tree.write("example.xml", encoding="utf-8", xml_declaration=True)
Run Code Online (Sandbox Code Playgroud)

结果"example.xml":

<?xml version='1.0' encoding='utf-8'?>
<fruits>
    <fruit>banana</fruit>
    <fruit>apple</fruit>
</fruits>
Run Code Online (Sandbox Code Playgroud)

  • 他通过了一个很好的解决方案 - 如果有任何安慰,我正在使用你的代码,它运作良好! (6认同)
  • 我也喜欢您的解决方案。我只需要更改函数中的第一行而不使用“ / n”,而是使用`os.linesep`使其在记事本(Windows)中正确获得新行。 (2认同)

Ste*_*ven 22

我认为最简单的解决方案是切换到lxml库.在大多数情况下,您只需将导入更改import xml.etree.ElementTree as etreefrom lxml import etree或类似.

然后,您可以pretty_print在序列化时使用该选项:

tree.write(filename, pretty_print=True)
Run Code Online (Sandbox Code Playgroud)

(也可提供etree.tostring)

  • /sf/ask/553263161/#7904066 在这里找到答案 (2认同)

gim*_*mel 13

ElementTree中没有漂亮的打印支持,但您可以使用其他XML模块.

例如,xml.dom.minidom.Node.toprettyxml():

Node.toprettyxml([indent=""[, newl=""[, encoding=""]]])

返回一个漂亮的文档版本.indent指定缩进字符串,默认为制表符; newl指定在每行末尾发出的字符串,默认为\n.

使用indentnewl满足您的要求.

例如,使用默认格式字符:

>>> from xml.dom import minidom
>>> from xml.etree import ElementTree
>>> tree1=ElementTree.XML('<tips><tip>1</tip><tip>2</tip></tips>')
>>> ElementTree.tostring(tree1)
'<tips><tip>1</tip><tip>2</tip></tips>'
>>> print minidom.parseString(ElementTree.tostring(tree1)).toprettyxml()
<?xml version="1.0" ?>
<tips>
    <tip>
        1
    </tip>
    <tip>
        2
    </tip>
</tips>

>>> 
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案,但唯一的问题是:为什么minidom会插入多余的空格(对于`1`和`2`;在xml中有意义)? (4认同)

小智 5

无需使用外部库,您可以通过将每个元素的 tail 属性设置为 来轻松实现输出中每个 XML 标记之间的换行符'\n'

您还可以在此处指定换行符后的制表符数量。然而,在 OP 的用例选项卡中,使用外部库可能更容易实现,或者参见 Erick M. Sprengel 的答案。

我在尝试使用 python 中的 xml.etree.ElementTree 修改 xml 文档时遇到了同样的问题。就我而言,我正在解析 xml 文件,清除某些元素(使用 Element.clear()),然后将结果写回文件。

对于我清除的每个元素,输出文件中其标记后没有新行。

ElementTree 的 Element.clear() 文档指出:

该函数删除所有子元素,清除所有属性,并将 text 和 tail 属性设置为 None。

这让我意识到元素的文本和尾部属性是确定输出格式的方式。就我而言,我可以将已清除元素的这些属性设置为与清除之前相同的值。该尾部值最终用于'\n\t'根 xml 元素的第一级子元素,其中选项卡的数量指示输出中显示的选项卡的数量。