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?

463voto

Ben Noland Punkte 32940
import xml.dom.minidom

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

194voto

1729 Punkte 4745

Lxml ist neu, aktualisiert und enthält eine hübsche Druckfunktion

import lxml.etree as etree

x = etree.parse("filename")
print etree.tostring(x, pretty_print=True)

Sehen Sie sich das lxml-Tutorial an: http://lxml.de/tutorial.html

122voto

ade Punkte 3996

Eine andere Lösung ist das Ausleihen este indent Funktion für die Verwendung mit der ElementTree-Bibliothek, die seit 2.5 in Python integriert ist. So würde das aussehen:

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)

81voto

ChaimG Punkte 5736

Sie haben mehrere Möglichkeiten.

xml.etree.ElementTree.indent()

Batterien im Lieferumfang enthalten, einfach zu bedienen, schöne Leistung.

Erfordert jedoch 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 ist vielleicht die einfachste Lösung für Python < 3.9.

from bs4 import BeautifulSoup

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

Sortie :

<?xml version="1.0" encoding="utf-8"?>
<issues>
 <issue>
  <id>
   1
  </id>
  <title>
   Add Visual Studio 2005 and 2008 solution files
  </title>
 </issue>
</issues>

Dies ist meine bevorzugte Antwort. Die Standardargumente funktionieren wie bisher. Aber die Textinhalte werden auf separate Zeilen verteilt, als ob sie verschachtelte Elemente wären.

lxml.etree.parse()

Hübschere Ausgabe, aber mit Argumenten.

from lxml import etree

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

Produziert:

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

Das funktioniert bei mir ohne Probleme.


xml.dom.minidom.parse()

Keine externen Abhängigkeiten, sondern Nachbearbeitung.

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

Die Ausgabe ist dieselbe wie oben, aber es ist mehr Code.

49voto

Nick Bolton Punkte 36172

Hier ist meine (hacky?) Lösung, um das Problem der hässlichen Textknoten zu umgehen.

uglyXml = doc.toprettyxml(indent='  ')

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

print prettyXml

Der obige Code erzeugt:

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

Stattdessen:

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

Haftungsausschluss: Es gibt wahrscheinlich einige Einschränkungen.

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