¿Cómo actualizar / modificar un archivo XML en python?

Tengo un documento XML que me gustaría actualizar después de que ya contiene datos.

Pensé en abrir el archivo XML en modo "a" (añadir). El problema es que los nuevos datos se escribirán después de la etiqueta de cierre de la raíz.

¿Cómo puedo eliminar la última línea de un archivo, luego comenzar a escribir datos desde ese punto y luego cerrar la etiqueta raíz?

Por supuesto, pude leer todo el archivo y hacer algunas manipulaciones de cadenas, pero no creo que esa sea la mejor idea …

Gracias por tu tiempo.

La forma rápida y fácil, que definitivamente no debería hacer (ver más abajo), es leer el archivo completo en una lista de cadenas usando readlines() . Escribo esto en caso de que la solución rápida y fácil sea lo que está buscando.

Simplemente abra el archivo usando open() , luego llame al método readlines() . Lo que obtendrás es una lista de todas las cadenas en el archivo. Ahora, puede agregar cadenas fácilmente antes del último elemento (solo agregue a la lista un elemento antes del último). Finalmente, puede escribirlos de nuevo en el archivo usando writelines() .

Un ejemplo podría ayudar:

 my_file = open(filename, "r") lines_of_file = my_file.readlines() lines_of_file.insert(-1, "This line is added one before the last line") my_file.writelines(lines_of_file) 

La razón por la que no debería hacer esto es porque, a menos que esté haciendo algo muy rápido y sucio, debería usar un analizador XML. Esta es una biblioteca que le permite trabajar con XML de forma inteligente, utilizando conceptos como DOM, árboles y nodos. Esta no es solo la forma correcta de trabajar con XML, sino también la forma estándar, haciendo que su código sea más portátil y más fácil de entender para otros progtwigdores.

La respuesta de Tim mencionó la comprobación de xml.dom.minidom para este propósito, lo que creo que sería una gran idea.

Utilizando ElementTree :

 import xml.etree.ElementTree # Open original file et = xml.etree.ElementTree.parse('file.xml') # Append new tag: body text new_tag = xml.etree.ElementTree.SubElement(et.getroot(), 'a') new_tag.text = 'body text' new_tag.attrib['x'] = '1' # must be str; cannot be an int new_tag.attrib['y'] = 'abc' # Write back to file #et.write('file.xml') et.write('file_new.xml') 

nota: la salida escrita en file_new.xml para que experimente, al escribir de nuevo en file.xml reemplazará el contenido anterior.

IMPORTANTE: la biblioteca de ElementTree almacena los atributos en un dict, como tal, el orden en el que se enumeran estos atributos en el texto xml NO se conservará. En su lugar, se emitirán en orden alfabético. (También, los comentarios son eliminados. Estoy encontrando esto bastante molesto)

es decir: el texto de entrada xml some body mostrará como some body (después de alfabetizar el los parámetros de orden están definidos)

Esto significa que al enviar los archivos originales y modificados a un sistema de control de revisión (como SVN, CSV, ClearCase, etc.), es posible que una diferencia entre los 2 archivos no se vea bien.

Analizadores útiles de Python XML:

  1. Minidom – funcional pero limitado
  2. ElementTree – rendimiento decente, más funcionalidad
  3. lxml : alto rendimiento en la mayoría de los casos , alta funcionalidad que incluye soporte xpath real

Cualquiera de esos es mejor que intentar actualizar el archivo XML como cadenas de texto.

Lo que eso significa para ti:

Abra su archivo con un analizador XML de su elección, encuentre el nodo que le interesa, reemplace el valor, vuelva a serializar el archivo.

Aunque estoy de acuerdo con Tim y Oben Sonne en que deberías usar una biblioteca XML, hay formas de manipularlo como un simple objeto de cadena.

Probablemente no intente usar un solo puntero de archivo para lo que está describiendo, y en lugar de eso, lea el archivo en la memoria, edítelo y luego escríbalo.

 inFile = open('file.xml', 'r') data = inFile.readlines() inFile.close() # some manipulation on `data` outFile = open('file.xml', 'w') outFile.writelines(data) outFile.close() 

Lo que realmente desea hacer es usar un analizador XML y agregar los nuevos elementos con la API proporcionada.

Luego simplemente sobrescriba el archivo.

El más fácil de usar probablemente sería un analizador DOM como el siguiente:

http://docs.python.org/library/xml.dom.minidom.html

Para hacer que este proceso sea más robusto, podría considerar usar el analizador SAX (de esa manera no tendrá que guardar todo el archivo en la memoria), leer y escribir hasta el final del árbol y luego comenzar a agregar.

Debe leer el archivo XML utilizando módulos XML específicos. De esa manera, puede editar el documento XML en la memoria y volver a escribir el documento XML modificado en el archivo.

Aquí tiene un inicio rápido: http://docs.python.org/library/xml.dom.minidom.html

Hay muchas otras utilidades XML, la mejor depende de la naturaleza de su archivo XML y de la forma en que quiera editarlo.

Como lo explicó Edan Maor, la forma rápida y sucia de hacerlo (para [. Utc-16] archivos .xml codificados), que no debe hacer por las razones que explicó Edam Maor, se puede hacer con el siguiente código de Python 2.7 en caso de restricciones de tiempo no te permiten aprender (propper) los análisis XML.

Suponiendo que usted quiere:

  1. Eliminar la última línea en el archivo xml original.
  2. Añadir una linea
  3. sustituir una línea
  4. Cierre la etiqueta raíz.

Funcionó en Python 2.7 modificando un archivo .xml llamado “b.xml” ubicado en la carpeta “a”, donde “a” estaba ubicado en la “carpeta de trabajo” de python. Da salida al nuevo archivo modificado como “c.xml” en la carpeta “a”, sin generar errores de encoding (para mí) en uso adicional fuera de Python 2.7.

 pattern = '' subst = ' ' + domain + '\\' + user_name + '' line_index =0 #set line count to 0 before starting file = io.open('a/b.xml', 'r', encoding='utf-16') lines = file.readlines() outFile = open('a/c.xml', 'w') for line in lines[0:len(lines)]: line_index =line_index +1 if line_index == len(lines): #1. & 2. delete last line and adding another line in its place not writing it outFile.writelines("Write extra line here" + '\n') # 4. Close root tag: outFile.writelines("") # as in: #http://tizag.com/xmlTutorial/xmldocument.php else: #3. Substitue a line if it finds the following substring in a line: pattern = '' subst = ' ' + domain + '\\' + user_name + '' if pattern in line: line = subst print line outFile.writelines(line)#just writing/copying all the lines from the original xml except for the last.