另一个解决方案是借用this indent function,与ElementTree库一起使用's built in to Python since 2.5. Here' s看起来像什么:
from xml.etree import ElementTree
def indent(elem, level=0):
i = "\n" + level*" "
j = "\n" + (level-1)*" "
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 subelem in elem:
indent(subelem, level+1)
if not elem.tail or not elem.tail.strip():
elem.tail = j
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = j
return elem
root = ElementTree.parse('/tmp/xmlfile').getroot()
indent(root)
ElementTree.dump(root)
<?xml version="1.0" ?>
<issues>
<issue>
<id>1</id>
<title>Add Visual Studio 2005 and 2008 solution files</title>
<details>We need Visual Studio 2005/2008 project files for Windows.</details>
</issue>
</issues>
而不是这个:
<?xml version="1.0" ?>
<issues>
<issue>
<id>
1
</id>
<title>
Add Visual Studio 2005 and 2008 solution files
</title>
<details>
We need Visual Studio 2005/2008 project files for Windows.
</details>
</issue>
</issues>
def indent(elem, level=0, more_sibs=False):
i = "\n"
if level:
i += (level-1) * ' '
num_kids = len(elem)
if num_kids:
if not elem.text or not elem.text.strip():
elem.text = i + " "
if level:
elem.text += ' '
count = 0
for kid in elem:
indent(kid, level+1, count < num_kids - 1)
count += 1
if not elem.tail or not elem.tail.strip():
elem.tail = i
if more_sibs:
elem.tail += ' '
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i
if more_sibs:
elem.tail += ' '
def toprettyxml(doc, encoding):
"""Return a pretty-printed XML document in a given encoding."""
unistr = doc.toprettyxml().replace(u'<?xml version="1.0" ?>',
u'<?xml version="1.0" encoding="%s"?>' % encoding)
return unistr.encode(encoding, 'xmlcharrefreplace')
140
from yattag import indent
pretty_string = indent(ugly_string)
def prettify(element, indent=' '):
queue = [(0, element)] # (level, element)
while queue:
level, element = queue.pop(0)
children = [(level + 1, child) for child in list(element)]
if children:
element.text = '\n' + indent * (level+1) # for child open
if queue:
element.tail = '\n' + indent * queue[0][0] # for sibling open
else:
element.tail = '\n' + indent * (level-1) # for parent close
queue[0:0] = children # prepend so children come before siblings
try:
with open(file_path, 'w') as file:
file.write('<?xml version="1.0" encoding="utf-8" ?>')
# create some xml content using etree ...
xml_parser = XMLParser()
xml_parser.write_xml_file(file, xml_root, xml_declaration=False, pretty_print=True, encoding='unicode', indent='\t')
except IOError:
print("Error while writing in log file!")
这样做只是因为etree默认使用 two spaces 来缩进,我不会为任何更改标准etree缩进的函数设置etree或参数 . 我喜欢使用etree是多么容易,但这真让我烦恼 .
3
For converting an entire xml document to a pretty xml document (例如:假设您已经解压缩[解压]了一个LibreOffice Writer .odt或.ods文件,并且您希望将丑陋的"content.xml"文件转换为非常适合自动git版本控制和.odt / .ods文件的 git difftool ,比如我正在实施here)
19 回答
您可以使用流行的外部库xmltodict,
unparse
和pretty=True
您将获得最佳结果:full_document=False
反对<?xml version="1.0" encoding="UTF-8"?>
在顶部 .如果您不想重新分析,则可以使用带有
get_pprint()
函数的xmlpp.py library . 对于我的用例,它工作得很顺利,而不必重新解析为lxml的ElementTree对象 .看一下vkbeautify模块 .
它是我非常流行的javascript / nodejs插件的python版本,具有相同的名称 . 它可以打印/缩小XML,JSON和CSS文本 . 输入和输出可以是任何组合的字符串/文件 . 它非常紧凑,没有任何依赖性 .
Examples :
lxml是最新的,更新的,并包含一个漂亮的打印功能
查看lxml教程:http://lxml.de/tutorial.html
另一个解决方案是借用this indent function,与ElementTree库一起使用's built in to Python since 2.5. Here' s看起来像什么:
这是我的(hacky?)解决方案来解决丑陋的文本节点问题 .
上面的代码将产生:
而不是这个:
免责声明:可能存在一些限制 .
正如其他人指出的那样,lxml内置了漂亮的打印机 .
请注意,默认情况下它会将CDATA部分更改为普通文本,这可能会产生令人讨厌的结果 .
这是一个Python函数,它保留输入文件,只更改缩进(注意
strip_cdata=False
) . 此外,它确保输出使用UTF-8作为编码而不是默认的ASCII(注意encoding='utf-8'
):用法示例:
BeautifulSoup有一个易于使用的
prettify()
功能 .它每个缩进级别缩进一个空格 . 它的效果比lxml的pretty_print好得多,而且简短而且甜美 .
如果你有
xmllint
,你可以生成一个子进程并使用它 .xmllint --format <file>
漂亮地将其输入XML打印到标准输出 .请注意,此方法使用python外部的程序,这使它成为一种黑客攻击 .
我尝试编辑上面的“ade”答案,但在我最初匿名提供反馈后,Stack Overflow不会让我编辑 . 这是一个不那么错误的版本的功能来漂亮地打印ElementTree .
如果你正在使用DOM实现,每个都有自己的内置漂亮打印形式:
如果你在没有自己的漂亮打印机的情况下使用别的东西 - 或者那些漂亮的打印机并不是你想要的那样 - 你可能必须编写或子类化你自己的序列化器 .
我遇到一些问题minidom 's pretty print. I' d每当我尝试使用给定编码之外的字符打印漂亮的文档时会得到一个UnicodeError,例如,如果我在文档中有一个β并且我尝试了
doc.toprettyxml(encoding='latin-1')
. 这是我的解决方法:它不会在文本节点中添加空格或换行符,除非您要求:
您可以指定缩进单元应该是什么以及换行应该是什么样的 .
该文档位于http://www.yattag.org主页上 .
XML pretty print for python看起来非常适合这项任务 . (也恰如其名 . )
另一种方法是使用pyXML,它有一个PrettyPrint function .
我编写了一个解决方案来遍历现有的ElementTree并使用text / tail来缩进它,就像人们通常期望的那样 .
我遇到了这个问题并解决了这个问题:
在我的代码中,这个方法被调用如下:
这样做只是因为etree默认使用
two spaces
来缩进,我不会为任何更改标准etree缩进的函数设置etree或参数 . 我喜欢使用etree是多么容易,但这真让我烦恼 .For converting an entire xml document to a pretty xml document
(例如:假设您已经解压缩[解压]了一个LibreOffice Writer .odt或.ods文件,并且您希望将丑陋的"content.xml"文件转换为非常适合自动git版本控制和.odt / .ods文件的
git difftool
,比如我正在实施here)参考文献:
我用一些代码解决了这个问题,打开文件,通过它并添加缩进,然后再次保存 . 我正在处理小的xml文件,并且不想添加依赖项,或者要为用户安装更多库 . 无论如何,这是我最终得到的:
它适用于我,也许有人会有一些使用它:)