c# - standalone - version 1.0 xml
Escritura de archivos XML usando XmlTextWriter con codificación ISO-8859-1 (6)
Tengo problemas para escribir caracteres noruegos en un archivo XML con C #. Tengo una variable de cadena que contiene texto noruego (con letras como æøå).
Estoy escribiendo el XML usando un XmlTextWriter, escribiendo el contenido en un MemoryStream como este:
MemoryStream stream = new MemoryStream();
XmlTextWriter xmlTextWriter = new XmlTextWriter(stream, Encoding.GetEncoding("ISO-8859-1"));
xmlTextWriter.Formatting = Formatting.Indented;
xmlTextWriter.WriteStartDocument(); //Start doc
Luego agrego mi texto noruego como este:
xmlTextWriter.WriteCData(myNorwegianText);
Luego escribo el archivo en el disco de esta manera:
FileStream myFile = new FileStream(myPath, FileMode.Create);
StreamWriter sw = new StreamWriter(myFile);
stream.Position = 0;
StreamReader sr = new StreamReader(stream);
string content = sr.ReadToEnd();
sw.Write(content);
sw.Flush();
myFile.Flush();
myFile.Close();
Ahora el problema es que en el archivo sobre esto, todos los personajes noruegos se ven divertidos.
Probablemente estoy haciendo lo anterior de alguna manera estúpida. ¿Alguna sugerencia sobre cómo solucionarlo?
¿Por qué estás escribiendo el XML primero en un MemoryStream y luego escribiéndolo en el flujo de archivos real? Eso es bastante ineficiente. Si escribe directamente en FileStream debería funcionar.
Si aún desea hacer la doble escritura, por cualquier razón, haga una de estas dos cosas. Ya sea
Asegúrese de que los objetos StreamReader y StreamWriter que utiliza utilizan la misma codificación que la que utilizó con XmlWriter (no solo StreamWriter, como sugirió otra persona), o
No use StreamReader / StreamWriter. En su lugar solo copie la secuencia en el nivel de bytes utilizando un byte simple [] y Stream.Read/Write. Esto va a ser, por cierto, mucho más eficiente de todos modos.
¿Qué codificación usas para mostrar el archivo de resultados? Si no está en ISO-8859-1, no se mostrará correctamente.
¿Hay alguna razón para usar esta codificación específica, en lugar de por ejemplo UTF8?
Debe configurar la codificación cada vez que escriba una cadena o lea datos binarios como una cadena.
Encoding encoding = Encoding.GetEncoding("ISO-8859-1");
FileStream myFile = new FileStream(myPath, FileMode.Create);
StreamWriter sw = new StreamWriter(myFile, encoding);
stream.Position = 0;
StreamReader sr = new StreamReader(stream, encoding);
string content = sr.ReadToEnd();
sw.Write(content);
sw.Flush();
myFile.Flush();
myFile.Close();
Tanto su StreamWriter como su StreamReader están usando UTF-8, porque no está especificando la codificación. Es por eso que las cosas se corrompen.
Como dijo tomasr, usar FileStream para empezar sería más simple, pero también MemoryStream tiene el práctico método "WriteTo" que te permite copiarlo fácilmente a FileStream.
Espero que tengas una declaración de uso en tu código real, por cierto, no quieres dejar tu archivo abierto si algo sale mal mientras escribes.
Jon
Como se menciona en las respuestas anteriores, el problema más importante aquí es la Encoding
, que se está incumpliendo debido a que no se especifica.
Cuando no especifica una Encoding
para este tipo de conversión, se utiliza el valor predeterminado de UTF-8
, que puede coincidir o no con su escenario. También está convirtiendo innecesariamente los datos empujándolos a un MemoryStream
y luego a un FileStream
.
Si sus datos originales no son UTF-8
, lo que sucederá aquí es que la primera transición al MemoryStream
intentará decodificarse utilizando la Encoding
de UTF-8
defecto y, como resultado, dañará sus datos. Cuando luego escribe en FileStream
, que también usa UTF-8
como codificación por defecto, simplemente persiste ese daño en el archivo.
Para solucionar el problema, es probable que deba especificar Encoding
en sus objetos Stream
.
En realidad, puede omitir el proceso MemoryStream
completo, lo que será más rápido y más eficiente. Su código actualizado puede parecerse más a esto:
FileStream fs = new FileStream(myPath, FileMode.Create);
XmlTextWriter xmlTextWriter =
new XmlTextWriter(fs, Encoding.GetEncoding("ISO-8859-1"));
xmlTextWriter.Formatting = Formatting.Indented;
xmlTextWriter.WriteStartDocument(); //Start doc
xmlTextWriter.WriteCData(myNorwegianText);
StreamWriter sw = new StreamWriter(fs);
fs.Position = 0;
StreamReader sr = new StreamReader(fs);
string content = sr.ReadToEnd();
sw.Write(content);
sw.Flush();
fs.Flush();
fs.Close();
Después de investigar, esto es lo que mejor funcionó para mí:
var doc = new XDocument(new XDeclaration("1.0", "ISO-8859-1", ""));
using (XmlWriter writer = doc.CreateWriter()){
writer.WriteStartDocument();
writer.WriteStartElement("Root");
writer.WriteElementString("Foo", "value");
writer.WriteEndElement();
writer.WriteEndDocument();
}
doc.Save("dte.xml");