527 Stimmen

Hübsches Drucken von XML in Python

Was ist der beste Weg (oder sind die verschiedenen Möglichkeiten) zu schön drucken XML in Python?

28voto

o15a3d4l11s2 Punkte 3850

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

23voto

roskakori Punkte 2729

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

13voto

Russell Silva Punkte 2612

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

11voto

Joshua Richardson Punkte 1590

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 += '  '

10voto

bobince Punkte 512550

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.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X