Was ist der beste Weg (oder sind die verschiedenen Möglichkeiten) zu schön drucken XML in Python?
Antworten
Zu viele Anzeigen?Ab Python 3.9 hat ElementTree eine indent()
Funktion für das Pretty-Printing von XML-Bäumen.
Voir https://docs.python.org/3/library/xml.etree.elementtree.html#xml.etree.ElementTree.indent .
Beispielhafte Verwendung:
import xml.etree.ElementTree as ET
element = ET.XML("<html><body>text</body></html>")
ET.indent(element)
print(ET.tostring(element, encoding='unicode'))
Der Vorteil ist, dass es keine zusätzlichen Bibliotheken benötigt. Für weitere Informationen siehe https://bugs.python.org/issue14465 y https://github.com/python/cpython/pull/15200
Wie bereits erwähnt, ist in lxml ein hübscher Drucker eingebaut.
Beachten Sie jedoch, dass CDATA-Abschnitte standardmäßig in normalen Text umgewandelt werden, was unangenehme Folgen haben kann.
Hier ist eine Python-Funktion, die die Eingabedatei beibehält und nur die Einrückung ändert (beachten Sie die strip_cdata=False
). Außerdem stellt es sicher, dass die Ausgabe UTF-8 als Kodierung anstelle des Standard-ASCII verwendet (beachten Sie die 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')
Beispiel für die Verwendung:
prettyPrintXml('some_folder/some_file.xml')
Wenn Sie eine xmllint
können Sie einen Unterprozess erzeugen und diesen verwenden. xmllint --format <file>
gibt seine XML-Eingabe in der Standardausgabe aus.
Beachten Sie, dass diese Methode ein Programm außerhalb von Python verwendet, was sie zu einer Art Hack macht.
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))
Ich habe versucht, die obige Antwort von "ade" zu bearbeiten, aber Stack Overflow ließ mich nicht bearbeiten, nachdem ich zunächst anonymes Feedback gegeben hatte. Dies ist eine weniger fehleranfällige Version der Funktion zum Pretty-Printing eines 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 += ' '
Wenn Sie eine DOM-Implementierung verwenden, hat jede ihre eigene Form des Pretty-Printing eingebaut:
# 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)
Wenn Sie etwas anderes verwenden, das keinen eigenen Pretty-Printer hat, oder wenn diese Pretty-Printer nicht ganz so funktionieren, wie Sie es wünschen, müssen Sie wahrscheinlich einen eigenen Serialisierer schreiben oder unterklassifizieren.