2009-06-09 12 views
15

Estoy tratando de crear una pieza de xml. Creé las clases de datos con xsd.exe. La clase raíz es MESSAGE.Problema de serialización XmlTextWriter

Así que después de la creación de un MESSAGE y llenar todas sus propiedades, que serializarlo así:

serializer = new XmlSerializer(typeof(Xsd.MESSAGE)); 
StringWriter sw = new StringWriter(); 
serializer.Serialize(sw, response); 
string xml = sw.ToString(); 

Hasta ahora todo va bien, la cadena XML contiene XML válido (UTF-16 codificada). Ahora me gusta para crear el XML con codificación UTF-8 en su lugar, por lo que de esta manera:

Editar: se olvidó de incluir la declaración de la corriente

serializer = new XmlSerializer(typeof(Xsd.MESSAGE)); 
using (MemoryStream stream = new MemoryStream()) 
{ 
    XmlTextWriter xtw = new XmlTextWriter(stream, Encoding.UTF8); 
    serializer.Serialize(xtw, response); 
    string xml = Encoding.UTF8.GetString(stream.ToArray()); 
} 

Y aquí viene el problema : Usando este enfoque, la cadena xml se antepone con un carácter no válido (el cuadrado infame).
Cuando inspeccione el carbón como esto:

char c = xml[0]; 

puedo ver que c tiene un valor de 65279.
alguien tiene una idea de dónde viene esto?
que puede resolver fácilmente este cortando el primer carácter:

xml = xml.SubString(1); 

Pero yo prefiero saber lo que está pasando que el corte a ciegas del primer carácter.

¿Alguien puede arrojar algo de luz sobre esto? ¡Gracias!

+0

Ver: http://stackoverflow.com/questions/955611/xmlwriter-to-write-to-a -string-instead-of-to-a-file/955698 # 955698 –

Respuesta

15

Aquí está el código modificado para no anteponer el orden de bytes-marca (BOM):

var serializer = new XmlSerializer(typeof(Xsd.MESSAGE)); 
Encoding utf8EncodingWithNoByteOrderMark = new UTF8Encoding(false); 
XmlTextWriter xtw = new XmlTextWriter(stream, utf8EncodingWithNoByteOrderMark); 
serializer.Serialize(xtw, response); 
string xml = Encoding.UTF8.GetString(stream.ToArray()); 
+0

Utilicé esta solución, así que acepté esta respuesta. ¡Gracias! – fretje

6

65279 es la marca de orden de bytes Unicode - ¿está seguro de que obtendrá 65249? Suponiendo que realmente es la lista de materiales, puede deshacerse de ella creando una instancia UTF8Encoding que no utiliza una lista de materiales. (Consulte las sobrecargas del constructor para obtener más información.)

Sin embargo, hay una manera más fácil de sacar el UTF-8. Puede usar StringWriter, pero una clase derivada que anula la propiedad Encoding. Ver this answer para un ejemplo.

+0

Ejecuté el código y obtuve 65279, también. Probablemente un error tipográfico en la pregunta. –

+0

Un error tipográfico ... actualizado ;-) – fretje

+0

BOM: ver http://en.wikipedia.org/wiki/Byte-order_mark –

Cuestiones relacionadas