用Python打印XML的最佳方法(或各种方法)是什么?


当前回答

如果你使用的是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)

如果您正在使用其他没有自己的漂亮打印机的东西——或者那些漂亮打印机不能完全按照您想要的方式来做——您可能必须编写或子类化您自己的序列化器。

其他回答

from yattag import indent

pretty_string = indent(ugly_string)

它不会在文本节点中添加空格或换行,除非你要求它:

indent(mystring, indent_text = True)

您可以指定缩进单位和换行符的样式。

pretty_xml_string = indent(
    ugly_xml_string,
    indentation = '    ',
    newline = '\r\n'
)

该文件在http://www.yattag.org主页上。

import xml.dom.minidom

dom = xml.dom.minidom.parse(xml_fname) # or xml.dom.minidom.parseString(xml_string)
pretty_xml_as_string = dom.toprettyxml()

我编写了一个解决方案来遍历现有的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

另一个解决方案是借用这个缩进函数,用于自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)

你有几个选择。

xml etree ElementTree。缩进()

包括电池,使用简单,输出漂亮。

但需要Python 3.9+

import xml.etree.ElementTree as ET

element = ET.XML("<html><body>text</body></html>")
ET.indent(element)
print(ET.tostring(element, encoding='unicode'))

BeautifulSoup.prettify ()

BeautifulSoup可能是Python < 3.9最简单的解决方案。

from bs4 import BeautifulSoup

bs = BeautifulSoup(open(xml_file), 'xml')
pretty_xml = bs.prettify()
print(pretty_xml)

输出:

<?XML版本="1.0"编码="utf-8"?> <问题> <问题> <标识> 1 < / id > <标题> 添加Visual Studio 2005和2008解决方案文件 < /名称> > < /问题 > < /问题

这是我要回答的。默认实参按原样工作。但是文本内容在单独的行上展开,就好像它们是嵌套的元素一样。

lxml.etree.parse()

更漂亮的输出,但是带有参数。

from lxml import etree

x = etree.parse(FILE_NAME)
pretty_xml = etree.tostring(x, pretty_print=True, encoding=str)

生产:

<问题> <问题> <标识> 1 > < / id <title>添加Visual Studio 2005和2008解决方案文件 <details>我们需要Visual Studio 2005/2008的Windows项目文件 > < /问题 > < /问题

这对我来说没什么问题。


xml dom minidom parse()。

没有外部依赖,只有后处理。

import xml.dom.minidom as md

dom = md.parse(FILE_NAME)     
# To parse string instead use: dom = md.parseString(xml_string)
pretty_xml = dom.toprettyxml()
# remove the weird newline issue:
pretty_xml = os.linesep.join([s for s in pretty_xml.splitlines()
                              if s.strip()])

输出与上面相同,但是代码更多。