Pregunta

Dado un flujo como entrada, ¿cómo puedo crear de forma segura un XPathNavigator contra una fuente de datos XML?

La fuente de datos XML:

  • Posiblemente puede contener caracteres hexadecimales no válidos que deben eliminarse.
  • Puede contener caracteres que no coincidan con la codificación declarada del documento.

Como ejemplo, algunas fuentes de datos XML en la nube tendrán una codificación declarada de utf-8 , pero la codificación real es windows-1252 o ISO 8859-1 , que puede provocar que se genere una excepción de carácter no válido al crear un XmlReader contra el Stream.

De la documentación de la propiedad StreamReader.CurrentEncoding : " La codificación de caracteres actual utilizada por el lector actual. El valor puede ser diferente después de la primera llamada a cualquier método de lectura de StreamReader, ya que la codificación de la autodetección no se realiza hasta la primera llamada a un método de lectura. & Quot; Parece que esto indica que CurrentEncoding se puede verificar después de la primera lectura, pero ¿estamos atascados almacenando esta codificación cuando necesitamos escribir los datos XML en un Stream?

Espero encontrar una mejor práctica para crear de forma segura una instancia de XPathNavigator / IXPathNavigable en una fuente de datos XML que manejará con gracia la codificación de los problemas de caracteres no válidos (preferiblemente en C #).

¿Fue útil?

Solución

Tuve un problema similar cuando algunos fragmentos XML se importaron a un sistema CRM utilizando la codificación incorrecta (no había ninguna codificación almacenada junto con los fragmentos XML).

En un bucle creé una secuencia de envoltorio usando la codificación actual de una lista. La codificación se construyó utilizando las opciones DecoderExceptionFallback y EncoderExceptionFallback (como lo menciona @Doug). Si se emitió una DecoderFallbackException durante el procesamiento, la secuencia original se restablece y se utiliza la siguiente codificación más probable.

Nuestra lista de codificación era algo como UTF-8, Windows-1252, GB-2312 y US-ASCII. Si se cayó del final de la lista, la transmisión fue realmente mala y fue rechazada / ignorada / etc.

EDITAR:

Preparé una muestra rápida y archivos de prueba básicos (fuente aquí ). El código no tiene heurísticas para elegir entre páginas de códigos que coincidan con el mismo conjunto de bytes, por lo que un archivo Windows-1252 puede detectarse como GB2312 y viceversa, según el contenido del archivo y el orden de preferencia de codificación.

Otros consejos

Es posible usar la clase DecoderFallback (y algunas clases relacionadas) para lidiar con los malos caracteres, ya sea saltándolos o haciendo otra cosa (¿reiniciar con una nueva codificación?).

Al usar un XmlTextReader o algo similar, el lector descubrirá la codificación declarada en el archivo xml.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top