web-dev-qa-db-fra.com

insertion de nouvelles lignes dans un fichier XML généré via xml.etree.ElementTree en python

J'ai créé un fichier XML à l'aide de xml.etree.ElementTree en python. J'utilise alors

tree.write(filename, "UTF-8") 

écrire le document dans un fichier.

Mais lorsque j'ouvre le nom de fichier à l'aide d'un éditeur de texte (vi sur linux), il n'y a pas de nouvelles lignes entre les balises. Tout est une grande ligne

Comment puis-je écrire le document dans un format "joli imprimé" afin qu'il y ait de nouvelles lignes (et, espérons-le, des indentations, etc.) entre toutes les balises XML?

Merci!

29
MK.

Je pense que la solution la plus simple est de passer à la bibliothèque lxml . Dans la plupart des cas, vous pouvez simplement changer votre importation de import xml.etree.ElementTree as etree à from lxml import etree ou similaire.

Vous pouvez ensuite utiliser l'option pretty_print lors de la sérialisation:

tree.write(filename, pretty_print=True)

(également disponible sur etree.tostring)

19
Steven

J'ai trouvé un nouveau moyen d'éviter de nouvelles bibliothèques et de reparsing le xml . Il vous suffit de passer votre élément racine à cette fonction (voir l'explication ci-dessous):

def indent(elem, level=0):
    i = "\n" + level*"  "
    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 elem in elem:
            indent(elem, level+1)
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i

Il existe un attribut nommé " tail " sur les instances xml.etree.ElementTree.Element . Cet attribut peut définir une chaîne après un nœud:

"<a>text</a>tail"

J'ai trouvé un lien de 2004 qui parle d'un Fonctions de la bibliothèque d'éléments qui utilise cette "queue" pour mettre en retrait un élément.

Exemple:

root = ET.fromstring("<fruits><fruit>banana</fruit><fruit>Apple</fruit></fruits>""")
tree = ET.ElementTree(root)

indent(root)
# writing xml
tree.write("example.xml", encoding="utf-8", xml_declaration=True)

Résultat sur "example.xml":

<?xml version='1.0' encoding='utf-8'?>
<fruits>
    <fruit>banana</fruit>
    <fruit>Apple</fruit>
</fruits>
42
Erick M. Sprengel

Selon ce fil votre meilleur choix serait d’installer pyXml et de l’utiliser pour prettyprint le contenu ElementTree xml (car ElementTree ne semble pas avoir une jolie imprimante par défaut en Python):

import xml.etree.ElementTree as ET

from xml.dom.ext.reader import Sax2
from xml.dom.ext import PrettyPrint
from StringIO import StringIO

def prettyPrintET(etNode):
    reader = Sax2.Reader()
    docNode = reader.fromString(ET.tostring(etNode))
    tmpStream = StringIO()
    PrettyPrint(docNode, stream=tmpStream)
    return tmpStream.getvalue()
0
ChristopheD