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


当前回答

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

其他回答

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

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

正如其他人指出的那样,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')

使用示例:

prettyPrintXml('some_folder/some_file.xml')

如果由于某种原因你无法获得其他用户提到的任何Python模块,我建议使用以下Python 2.7解决方案:

import subprocess

def makePretty(filepath):
  cmd = "xmllint --format " + filepath
  prettyXML = subprocess.check_output(cmd, shell = True)
  with open(filepath, "w") as outfile:
    outfile.write(prettyXML)

据我所知,这种解决方案适用于安装了xmllint包的基于unix的系统。

下面是我解决难看的文本节点问题的解决方案。

uglyXml = doc.toprettyxml(indent='  ')

text_re = re.compile('>\n\s+([^<>\s].*?)\n\s+</', re.DOTALL)    
prettyXml = text_re.sub('>\g<1></', uglyXml)

print prettyXml

上面的代码将产生:

<?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>

免责声明:可能有一些限制。

你可以试试这种变化……

安装BeautifulSoup和后端lxml(解析器)库:

user$ pip3 install lxml bs4

处理XML文档:

from bs4 import BeautifulSoup

with open('/path/to/file.xml', 'r') as doc: 
    for line in doc: 
        print(BeautifulSoup(line, 'lxml-xml').prettify())