使用lxml的Python美化XML打印机

36 投票
6 回答
57350 浏览
提问于 2025-04-16 12:21

在读取一个已经存在的、格式很糟糕的XML文件并进行了一些修改后,想要让它变得好看,但发现美化输出没有效果。我试过用 etree.write(FILE_NAME, pretty_print=True)

我有以下这个XML:

<testsuites tests="14" failures="0" disabled="0" errors="0" time="0.306" name="AllTests">
    <testsuite name="AIR" tests="14" failures="0" disabled="0" errors="0" time="0.306">
....

我这样使用它:

tree = etree.parse('original.xml')
root = tree.getroot()

...    
# modifications
...

with open(FILE_NAME, "w") as f:
    tree.write(f, pretty_print=True)

6 个回答

7

这里有一个适用于Python 3的解决方案:

from lxml import etree
from sys import stdout
from io import BytesIO

parser = etree.XMLParser(remove_blank_text = True)
file_obj = BytesIO(text)
tree = etree.parse(file_obj, parser)
tree.write(stdout.buffer, pretty_print = True)

其中,text 是以字节序列形式表示的xml代码。

19

根据API文档,lxml的etree模块里没有“write”这个方法。如果你想把格式化好的XML字符串保存到文件里,有几种选择。你可以使用tostring方法,像这样:

f = open('doc.xml', 'w')
f.write(etree.tostring(root, pretty_print=True))
f.close()

另外,如果你的输入数据不太完美,或者你想要更多的选项来调整输出格式,可以使用一些Python的包装库来配合tidy库。

http://utidylib.berlios.de/

import tidy
f.write(tidy.parseString(your_xml_str, **{'output_xml':1, 'indent':1, 'input_xml':1}))

http://countergram.com/open-source/pytidylib

from tidylib import tidy_document
document, errors = tidy_document(your_xml_str, options={'output_xml':1, 'indent':1, 'input_xml':1})
f.write(document)
80

对我来说,这个问题一直没解决,直到我注意到这里的一点小信息:

http://lxml.de/FAQ.html#why-doesn-t-the-pretty-print-option-reformat-my-xml-output

简单来说:

用这个命令读取文件:

>>> parser = etree.XMLParser(remove_blank_text=True)
>>> tree = etree.parse(filename, parser)

这样可以“重置”已经存在的缩进,让输出能够正确生成自己的缩进。然后像往常一样使用 pretty_print:

>>> tree.write(<output_file_name>, pretty_print=True)

撰写回答