2010-12-19 18 views
5

Estoy intentando escribir el contenido del objeto xml.dom.minidom en el archivo. La idea sencilla es utilizar el método 'WriteXml':Escribir XML en el archivo daña los archivos en python

import codecs 

def write_xml_native(): 
    # Building DOM from XML 
    xmldoc = minidom.parse('semio2.xml') 
    f = codecs.open('codified.xml', mode='w', encoding='utf-8') 
    # Using native writexml() method to write 
    xmldoc.writexml(f, encoding="utf=8") 
    f.close() 

El problema es que corrompe el texto no latino-codificado en el archivo. La otra manera es conseguir la cadena de texto y escribirlo para presentar de manera explícita:

def write_xml(): 
    # Building DOM from XML 
    xmldoc = minidom.parse('semio2.xml') 
    # Opening file for writing UTF-8, which is XML's default encoding 
    f = codecs.open('codified3.xml', mode='w', encoding='utf-8') 
    # Writing XML in UTF-8 encoding, as recommended in the documentation 
    f.write(xmldoc.toxml("utf-8")) 
    f.close() 

Esto da como resultado el siguiente error:

Traceback (most recent call last): 
    File "D:\Projects\Semio\semioparser.py", line 45, in <module> 
    write_xml() 
    File "D:\Projects\Semio\semioparser.py", line 42, in write_xml 
    f.write(xmldoc.toxml(encoding="utf-8")) 
    File "C:\Python26\lib\codecs.py", line 686, in write 
    return self.writer.write(data) 
    File "C:\Python26\lib\codecs.py", line 351, in write 
    data, consumed = self.encode(object, self.errors) 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 2064: ordinal not in range(128) 

¿Cómo se escribe un texto XML para presentar? ¿Qué es lo que me estoy perdiendo?

EDIT. El error se soluciona agregando la declaración de decodificación: f.write(xmldoc.toxml("utf-8").decode("utf-8")) Pero los símbolos rusos todavía están dañados.

El texto no está dañado cuando se lo ve en un intérprete, pero cuando está escrito en un archivo.

+1

Sólo un pensamiento: ¿Estás seguro no estás viendo el archivo incorrectamente? Tal vez el lector está esperando otra codificación que utf-8 y se ve borked. – Nubsis

+0

@Nubsis Eso es exactamente lo que estaba pasando. El espectador esperaba la codificación ASCII. Mantendré el hilo porque usar .decode() también fue el problema. ¡Gracias! – martinthenext

Respuesta

9

Hmm, aunque esto debería funcionar:

xml = minidom.parse("test.xml") 
with codecs.open("out.xml", "w", "utf-8") as out: 
    xml.writexml(out) 

que alternativamente puede probar:

with codecs.open("test.xml", "r", "utf-8") as inp: 
    xml = minidom.parseString(inp.read().encode("utf-8")) 
with codecs.open("out.xml", "w", "utf-8") as out: 
    xml.writexml(out) 

actualización: En caso de construcción XML de objeto de cadena, debe codificarlo antes de pasar minidom parser, como este:

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

import codecs 
import xml.dom.minidom as minidom 

xml = minidom.parseString(u"<ru>Тест</ru>".encode("utf-8")) 
with codecs.open("out.xml", "w", "utf-8") as out: 
    xml.writexml(out) 
+0

Gracias por su respuesta. He probado todo tu código, nada de eso funciona bien para mí. Incluso la última pieza, que no tiene nada que ver con la apertura de un archivo XML, traduce la cadena rusa en una tontería. Esto significa que el problema está en escribir urf-8 en los archivos. ¿Alguna idea más? – martinthenext

+0

@martinthenext: estoy casi seguro de que obtiene el "utf-8" válido (los 3 ejemplos funcionan bien para mí, tanto en windows & linux como en python 2.5, 2.6 y 2.7) o su instalación de Python está rota; aquí va la captura de pantalla: http://img190.imageshack.us/img190/9072/minidom.png –

+0

Espera, la salida del intérprete en sí está bien, no hay problemas con eso. Se corrompe cuando se escribe en un archivo. ¿Cómo puedo arreglar esto? – martinthenext

0

Prueba esto:

with open("codified.xml", "w") as f: 
    f.write(xmldoc.toxml("utf-8").decode("utf-8")) 

Esto funciona para mí (en Python 3, sin embargo).

+0

no, aún daña caracteres no latinos – martinthenext

+0

¿Qué sucede si 'x = codecs.open (" semio2.xml ", encoding =" utf-8 ")' y 'xmldoc = minidom.parse (x)'? –

+0

dice 'UnicodeEncodeError: 'ascii' códec no puede codificar el carácter u '\ ufeff' en la posición 0: ordinal no en el rango (128)'. No puedo entender por qué. – martinthenext

Cuestiones relacionadas