Explicación UTF-8 Encoding y porque el XmlDocument da problemas
La codificación UTF-8 es una de las más utilizadas para representar cualquier carácter Unicode. La codificación usa símbolos de longitud variable (de 1 a 4 bytes por carácter unicode). Es decir, que 1 carcater unicode puede ocupar hasta 4 bytes, cuando en ascii 1 caracter es 1 byte.
Una forma de identificar que el texto esta codificado en UTF-8 es con el BOM Byte Order Mark, que son una serie de 3 bytes concretos. Útil por ejemplo en el envio de texto por stream.
un carácter 0xFEFF, codificado en UTF-8 como 0xEF,0xBB,0xBF o 239 187 191
Resumiendo, si al principio del texto vienen estos bytes significa que la codificación es UTF-8, de esta forma el receptor puede identificarlo y tratar el texto con el “Encoding” correcto. El problema es que el BOM es opcional en la definición UTF-8 y no siempre es soportado por el software que debe leer texto UTF8. Por ejemplo en PHP puede causar problemas, algunos programas de Microsoft lo incorporan automáticamente y otros no lo soportan, en conclusión hay que tener cuidado con su uso y asegurarse que el receptor sabe interpretarlo correctamente.
Más información en BOM Byte Order Mark.
XmlDocument desde .Net
La clase XmlDocument no soporta cargar un Xml con el BOM incorporado, dará error. Si os fijais, veremos en un String con un Xml en UTF8 y el BOM que los 3 primeros bytes son 239 187 191.
La forma de poder cargar un XML con BOM utilizando la clase XmlDocument es utilizar la clase UTF8Encoding
De alguna forma crear una clase UTF8 sin BOM y convertirlo,
String utf8WithoutBom = new System.Text.UTF8Encoding(False);
O Crear una clase con BOM y utilizar el método “GetPreamble” para saber si el texto lo contiene y en tal caso eliminarlo.
UTF8Encoding utf8WithBom = new System.Text.UTF8Encoding(true);
string byteOrderMarkUtf8 = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
if (xml.StartsWith(byteOrderMarkUtf8))
{
xml = xml.Remove(0, byteOrderMarkUtf8.Length);
}
Las claves están aquí, sólo hay que encontrar como utilizarlas correctamente.