Ben*_*and 362
import xml.dom.minidom
dom = xml.dom.minidom.parse(xml_fname) # or xml.dom.minidom.parseString(xml_string)
pretty_xml_as_string = dom.toprettyxml()
Run Code Online (Sandbox Code Playgroud)
172*_*729 154
lxml是最新的,更新的,并包含一个漂亮的打印功能
import lxml.etree as etree
x = etree.parse("filename")
print etree.tostring(x, pretty_print=True)
Run Code Online (Sandbox Code Playgroud)
查看lxml教程:http: //lxml.de/tutorial.html
ade*_*ade 105
另一个解决方案是借用这个indent
函数,与2.5之后内置于Python的ElementTree库一起使用.这是什么样子:
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)
Run Code Online (Sandbox Code Playgroud)
Nic*_*ton 47
这是解决丑陋文本节点问题的(hacky?)解决方案.
uglyXml = doc.toprettyxml(indent=' ')
text_re = re.compile('>\n\s+([^<>\s].*?)\n\s+</', re.DOTALL)
prettyXml = text_re.sub('>\g<1></', uglyXml)
print prettyXml
Run Code Online (Sandbox Code Playgroud)
上面的代码将产生:
<?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>
Run Code Online (Sandbox Code Playgroud)
而不是这个:
<?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>
Run Code Online (Sandbox Code Playgroud)
免责声明:可能存在一些限制.
ros*_*ori 22
正如其他人所指出的那样,lxml内置了漂亮的打印机.
请注意,默认情况下它会将CDATA部分更改为普通文本,这可能会产生令人讨厌的结果.
这是一个Python函数,它保留输入文件,只更改缩进(注意strip_cdata=False
).此外,它确保输出使用UTF-8作为编码而不是默认的ASCII(注意encoding='utf-8'
):
from lxml import etree
def prettyPrintXml(xmlFilePathToPrettyPrint):
assert xmlFilePathToPrettyPrint is not None
parser = etree.XMLParser(resolve_entities=False, strip_cdata=False)
document = etree.parse(xmlFilePathToPrettyPrint, parser)
document.write(xmlFilePathToPrettyPrint, pretty_print=True, encoding='utf-8')
Run Code Online (Sandbox Code Playgroud)
用法示例:
prettyPrintXml('some_folder/some_file.xml')
Run Code Online (Sandbox Code Playgroud)
Cha*_*imG 17
BeautifulSoup有一个易于使用的prettify()
方法.
它每个缩进级别缩进一个空格.它比lxml的pretty_print好得多,而且简短而且甜美.
from bs4 import BeautifulSoup
bs = BeautifulSoup(open(xml_file), 'xml')
print bs.prettify()
Run Code Online (Sandbox Code Playgroud)
o15*_*1s2 17
从 Python 3.9 开始,ElementTree 有一个indent()
用于漂亮打印 XML 树的函数。
请参阅https://docs.python.org/3/library/xml.etree.elementtree.html#xml.etree.ElementTree.indent。
示例用法:
import xml.etree.ElementTree as ET
element = ET.XML("<html><body>text</body></html>")
ET.indent(element)
print(ET.tostring(element, encoding='unicode'))
Run Code Online (Sandbox Code Playgroud)
好处是它不需要任何额外的库。有关更多信息,请查看https://bugs.python.org/issue14465和https://github.com/python/cpython/pull/15200
Jos*_*son 11
我尝试编辑上面的"ade"答案,但是在我最初匿名提供反馈后,Stack Overflow不会让我编辑.这是一个不那么错误的版本的功能,以漂亮地打印ElementTree.
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 += ' '
Run Code Online (Sandbox Code Playgroud)
Rus*_*lva 10
如果你有,xmllint
你可以产生一个子进程并使用它.xmllint --format <file>
漂亮地将其输入XML打印到标准输出.
请注意,此方法使用python外部的程序,这使它成为一种黑客攻击.
def pretty_print_xml(xml):
proc = subprocess.Popen(
['xmllint', '--format', '/dev/stdin'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
)
(output, error_output) = proc.communicate(xml);
return output
print(pretty_print_xml(data))
Run Code Online (Sandbox Code Playgroud)
如果你正在使用DOM实现,每个都有自己的内置漂亮打印形式:
# minidom
#
document.toprettyxml()
# 4DOM
#
xml.dom.ext.PrettyPrint(document, stream)
# pxdom (or other DOM Level 3 LS-compliant imp)
#
serializer.domConfig.setParameter('format-pretty-print', True)
serializer.writeToString(document)
Run Code Online (Sandbox Code Playgroud)
如果你在没有自己的漂亮打印机的情况下使用别的东西 - 或者那些漂亮的打印机不能按照你想要的方式完成它 - 你可能必须编写或子类化你自己的序列化器.
我对minidom漂亮的印刷品有一些问题.每当我尝试使用给定编码之外的字符打印漂亮的文档时,我会得到一个UnicodeError,例如,如果我在文档中有一个β而且我试过了doc.toprettyxml(encoding='latin-1')
.这是我的解决方法:
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')
Run Code Online (Sandbox Code Playgroud)
from yattag import indent
pretty_string = indent(ugly_string)
Run Code Online (Sandbox Code Playgroud)
它不会在文本节点中添加空格或换行符,除非您要求:
indent(mystring, indent_text = True)
Run Code Online (Sandbox Code Playgroud)
您可以指定缩进单元应该是什么以及换行应该是什么样的.
pretty_xml_string = indent(
ugly_xml_string,
indentation = ' ',
newline = '\r\n'
)
Run Code Online (Sandbox Code Playgroud)
该文档位于http://www.yattag.org主页.
我编写了一个解决方案来遍历现有的 ElementTree 并使用 text/tail 将其缩进,正如人们通常所期望的那样。
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
Run Code Online (Sandbox Code Playgroud)
这是一个 Python3 解决方案,它消除了丑陋的换行问题(大量空格),并且与大多数其他实现不同,它只使用标准库。
import xml.etree.ElementTree as ET
import xml.dom.minidom
import os
def pretty_print_xml_given_root(root, output_xml):
"""
Useful for when you are editing xml data on the fly
"""
xml_string = xml.dom.minidom.parseString(ET.tostring(root)).toprettyxml()
xml_string = os.linesep.join([s for s in xml_string.splitlines() if s.strip()]) # remove the weird newline issue
with open(output_xml, "w") as file_out:
file_out.write(xml_string)
def pretty_print_xml_given_file(input_xml, output_xml):
"""
Useful for when you want to reformat an already existing xml file
"""
tree = ET.parse(input_xml)
root = tree.getroot()
pretty_print_xml_given_root(root, output_xml)
Run Code Online (Sandbox Code Playgroud)
我在这里找到了如何解决常见的换行问题。
归档时间: |
|
查看次数: |
328977 次 |
最近记录: |