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


当前回答

使用etree。缩进和etree.tostring

import lxml.etree as etree

root = etree.fromstring('<html><head></head><body><h1>Welcome</h1></body></html>')
etree.indent(root, space="  ")
xml_string = etree.tostring(root, pretty_print=True).decode()
print(xml_string)

输出

<html>
  <head/>
  <body>
    <h1>Welcome</h1>
  </body>
</html>

删除名称空间和前缀

import lxml.etree as etree


def dump_xml(element):
    for item in element.getiterator():
        item.tag = etree.QName(item).localname

    etree.cleanup_namespaces(element)
    etree.indent(element, space="  ")
    result = etree.tostring(element, pretty_print=True).decode()
    return result


root = etree.fromstring('<cs:document xmlns:cs="http://blabla.com"><name>hello world</name></cs:document>')
xml_string = dump_xml(root)
print(xml_string)

输出

<document>
  <name>hello world</name>
</document>

其他回答

从Python 3.9开始,ElementTree有一个用于漂亮打印XML树的indent()函数。

见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'))

好处是它不需要任何额外的库。欲了解更多信息,请访问https://bugs.python.org/issue14465和https://github.com/python/cpython/pull/15200

你有几个选择。

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()])

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

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

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

用于将整个xml文档转换为漂亮的xml文档 (例如:假设你已经解压缩了一个LibreOffice Writer .odt或.ods文件,你想把这个丑陋的“content.xml”文件转换成一个漂亮的文件,用于自动化git版本控制和git的。odt/。ods文件,比如我在这里实现的)

import xml.dom.minidom

file = open("./content.xml", 'r')
xml_string = file.read()
file.close()

parsed_xml = xml.dom.minidom.parseString(xml_string)
pretty_xml_as_string = parsed_xml.toprettyxml()

file = open("./content_new.xml", 'w')
file.write(pretty_xml_as_string)
file.close()

引用: -感谢本·诺兰德在本页上的回答,让我有了大部分的了解。

我遇到了这个问题,我是这样解决的:

def write_xml_file (self, file, xml_root_element, xml_declaration=False, pretty_print=False, encoding='unicode', indent='\t'):
    pretty_printed_xml = etree.tostring(xml_root_element, xml_declaration=xml_declaration, pretty_print=pretty_print, encoding=encoding)
    if pretty_print: pretty_printed_xml = pretty_printed_xml.replace('  ', indent)
    file.write(pretty_printed_xml)

在我的代码中,这个方法是这样调用的:

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默认使用两个空格来缩进,我发现这不是很强调缩进,因此不漂亮。我找不到任何树的设置或任何函数的参数来改变标准树缩进。我喜欢使用etree的简单性,但这真的让我很恼火。