library example etree dict datacamp create python xml

example - xml python 3



insertando nuevas líneas en el archivo xml generado a través de xml.etree.ElementTree en python (4)

He creado un archivo xml usando xml.etree.ElementTree en python. Entonces uso

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

para escribir el documento en un archivo.

Pero cuando abro el nombre de archivo usando un editor de texto (vi en linux), no hay nuevas líneas entre las etiquetas. Todo es una gran linea

¿Cómo puedo escribir el documento en un formato "bastante impreso" para que haya nuevas líneas (y, con suerte, sangrías, etc.) entre todas las etiquetas xml?

¡Gracias!


Creo que la solución más fácil es cambiar a la biblioteca lxml . En la mayoría de los casos, simplemente puede cambiar su importación de import xml.etree.ElementTree as etree a from lxml import etree o similar.

Luego puede usar la opción pretty_print cuando pretty_print :

tree.write(filename, pretty_print=True)

(también disponible en etree.tostring )


Encontré una nueva forma de evitar nuevas bibliotecas y volver a compartir el xml. Solo necesita pasar su elemento raíz a esta función (vea la explicación a continuación):

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

Hay un atributo llamado " tail " en instancias de xml.etree.ElementTree.Element. Este atributo puede establecer una cadena después de un nodo:

"<a>text</a>tail"

Encontré un enlace de 2004 que hablaba sobre las Funciones de la Biblioteca de Elementos que usa esta "cola" para sangrar un elemento.

Ejemplo:

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)

Resultado en "example.xml":

<?xml version=''1.0'' encoding=''utf-8''?> <fruits> <fruit>banana</fruit> <fruit>apple</fruit> </fruits>


No existe un soporte de impresión bonito en ElementTree, pero puede utilizar otros módulos XML.

Por ejemplo, xml.dom.minidom.Node.toprettyxml() :

Node.toprettyxml([indent=""[, newl=""[, encoding=""]]])

Devuelva una versión bonita impresa del documento. sangría especifica la cadena de sangría y por defecto a un tabulador; newl especifica la cadena emitida al final de cada línea y su valor predeterminado es / n.

Utilice indent y newl para satisfacer sus necesidades.

Un ejemplo, usando los caracteres de formato por defecto:

>>> from xml.dom import minidom >>> from xml.etree import ElementTree >>> tree1=ElementTree.XML(''<tips><tip>1</tip><tip>2</tip></tips>'') >>> ElementTree.tostring(tree1) ''<tips><tip>1</tip><tip>2</tip></tips>'' >>> print minidom.parseString(ElementTree.tostring(tree1)).toprettyxml() <?xml version="1.0" ?> <tips> <tip> 1 </tip> <tip> 2 </tip> </tips> >>>


De acuerdo con este hilo, lo mejor sería instalar pyXml y usarlo para prettyprint el contenido XML de ElementTree (ya que ElementTree no parece tener una impresora bonita de forma predeterminada 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()