2010-06-22 14 views
26

He creado un archivo xml usando xml.etree.ElementTree en python. Luego usoinsertando líneas nuevas en el archivo xml generado a través de xml.etree.ElementTree en python

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

para escribir el documento en un archivo.

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

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

Gracias!

Respuesta

16

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

continuación, puede utilizar la opción pretty_print al serializar:

tree.write(filename, pretty_print=True) 

(también disponible en etree.tostring)

+0

Gracias Steven. Esto es lo que terminé haciendo. –

0

According to this thread la mejor opción sería instalar pyXml y el uso que prettyprint el contenido ElementTree XML (como no parece tener un elementtree prettyprinter por defecto 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() 
9

No hay impresión bastante soporte en ElementTree, pero puede utilizar otros módulos XML.

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

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

Devuelve una versión impresa del documento. sangrado especifica la cadena de sangrado y se predetermina 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 ajustarse a sus necesidades.

Un ejemplo, utilizando el formato predeterminado caracteres:

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

>>> 
+3

Buena respuesta, pero la única pregunta es: ¿por qué minidom insertar espacios en blanco extraenous (por '' 1' y 2 '; significativo en xml)? – ChristopheD

+0

Buena pregunta ;-) Usar con cuidado. – gimel

+0

Modificar sangría y nueval. – gimel

26

He encontrado una nueva manera de evitar nuevas bibliotecas y reparsing el código XML. Sólo tiene que pasar su elemento raíz de esta función (véase más adelante la explicació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 denominado "tail" en casos xml.etree.ElementTree.Element. Este atributo se puede establecer una cadena después de un nodo:

"<a>text</a>tail" 

me encontré con un enlace desde 2004 hablando de un Element Library Functions que utiliza 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 de "example.xml":

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

Él le dio el alto en una gran solución; si le sirve de consuelo, estoy usando su código y ¡funciona bien! – Dagrooms

Cuestiones relacionadas