leer - xml python 3
¿Cómo consigo que ElementTree de Python se imprima en un archivo XML? (5)
Cualquiera que sea su cadena XML, puede escribirla en el archivo de su elección abriendo un archivo para escribir y escribir la cadena en el archivo.
from xml.dom import minidom
xmlstr = minidom.parseString(ET.tostring(root)).toprettyxml(indent=" ")
with open("New_Database.xml", "w") as f:
f.write(xmlstr)
Hay una posible complicación, especialmente en Python 2, que es menos estricta y menos sofisticada sobre los caracteres Unicode en las cadenas.
Si su método
toprettyxml
devuelve una cadena Unicode (
u"something"
), es posible que desee convertirlo a una codificación de archivo adecuada, como UTF-8.
Por ejemplo, reemplace la línea de escritura con:
f.write(xmlstr.encode(''utf-8''))
Antecedentes
Estoy usando SQLite para acceder a una base de datos y recuperar la información deseada. Estoy usando ElementTree en Python versión 2.6 para crear un archivo XML con esa información.
Código
import sqlite3
import xml.etree.ElementTree as ET
# NOTE: Omitted code where I acccess the database,
# pull data, and add elements to the tree
tree = ET.ElementTree(root)
# Pretty printing to Python shell for testing purposes
from xml.dom import minidom
print minidom.parseString(ET.tostring(root)).toprettyxml(indent = " ")
####### Here lies my problem #######
tree.write("New_Database.xml")
Intentos
Intenté usar
tree.write("New_Database.xml", "utf-8")
en lugar de la última línea de código anterior, pero no editó el diseño del XML, sigue siendo un desastre.
También decidí juguetear e intenté hacer:
tree = minidom.parseString(ET.tostring(root)).toprettyxml(indent = " ")
en lugar de imprimir esto en el shell de Python, lo que da el error
AttributeError: el objeto ''unicode'' no tiene el atributo ''write''
.
Preguntas
Cuando escribo mi árbol en un archivo XML en la última línea, ¿hay alguna manera de imprimir bastante en el archivo XML como lo hace en el shell de Python?
¿Puedo usar
toprettyxml()
aquí o hay una forma diferente de hacerlo?
Echa un vistazo al módulo vkbeautify .
La entrada y la salida pueden ser cadenas / archivos en cualquier combinación. Es muy compacto y no tiene ninguna dependencia.
import vkbeautify as vkb
a) pretty_text = vkb.xml(your_xml_text) #return String
b) vkb.xml(your_xml_text, ''path/to/dest/file'') #save in file
Encontré una manera de usar ElementTree directo, pero es bastante complejo.
ElementTree tiene funciones que editan el texto y la cola de elementos, por ejemplo,
element.text="text"
y
element.tail="tail"
.
Debe usarlos de una manera específica para alinear las cosas, así que asegúrese de conocer a sus personajes de escape.
Como ejemplo básico:
Tengo el siguiente archivo:
<?xml version=''1.0'' encoding=''utf-8''?>
<root>
<data version="1">
<data>76939</data>
</data>
<data version="2">
<data>266720</data>
<newdata>3569</newdata>
</data>
</root>
Para colocar un tercer elemento y mantenerlo bonito, necesita el siguiente código:
addElement = ET.Element("data") # Make a new element
addElement.set("version", "3") # Set the element''s attribute
addElement.tail = "/n" # Edit the element''s tail
addElement.text = "/n/t/t" # Edit the element''s text
newData = ET.SubElement(addElement, "data") # Make a subelement and attach it to our element
newData.tail = "/n/t" # Edit the subelement''s tail
newData.text = "5431" # Edit the subelement''s text
root[-1].tail = "/n/t" # Edit the previous element''s tail, so that our new element is properly placed
root.append(addElement) # Add the element to the tree.
Para sangrar las etiquetas internas (como la etiqueta de datos interna), debe agregarlo al texto del elemento primario. Si desea sangrar algo después de un elemento (generalmente después de subelementos), póngalo en la cola.
Este código da el siguiente resultado cuando lo escribe en un archivo:
<?xml version=''1.0'' encoding=''utf-8''?>
<root>
<data version="1">
<data>76939</data>
</data>
<data version="2">
<data>266720</data>
<newdata>3569</newdata>
</data> <!--root[-1].tail-->
<data version="3"> <!--addElement''s text-->
<data>5431</data> <!--newData''s tail-->
</data> <!--addElement''s tail-->
</root>
Como otra nota, si desea que el programa use uniformemente
/t
, es posible que primero desee analizar el archivo como una cadena y reemplazar todos los espacios para las sangrías con
/t
.
Este código se creó en Python3.7, pero aún funciona en Python2.7.
Instalar
bs4
pip install bs4
Use este código para imprimir bonito:
from bs4 import BeautifulSoup
x = your xml
print(BeautifulSoup(x, "xml").prettify())
Si se quiere usar lxml, se podría hacer de la siguiente manera:
from lxml import etree
xml_object = etree.tostring(root,
pretty_print=True,
xml_declaration=True,
encoding=''UTF-8'')
with open("xmlfile.xml", "wb") as writter:
writter.write(xml_object)`
Si ve espacios de nombres xml, por ejemplo
py:pytype="TREE"
, es posible que desee agregarlos antes de crear
xml_object
etree.cleanup_namespaces(root)
Esto debería ser suficiente para cualquier adaptación en su código.