2009-05-12 29 views
12

Estoy trabajando en un pequeño proyecto que está recibiendo datos XML en forma de cadena desde una aplicación de ejecución larga. Estoy tratando de cargar esta cadena de datos en un XDocument (System.Xml.Linq.XDocument), y a partir de allí hacer algo de XML Magic y crear un archivo xlsx para un informe sobre los datos.Excepción XML: carácter (s) inválido (s)

En ocasiones, recibo los datos que tienen caracteres XML no válidos, y cuando intento analizar la cadena en un XDocument, obtengo este error.

[System.Xml.XmlException] mensaje: '?', Valor hexadecimal 0x1C, es un carácter no válido.

Como no tengo control sobre la aplicación remota, puede esperar CUALQUIER tipo de carácter.

Soy muy consciente de que XML tiene una manera en la que puede poner caracteres como &#x1C o algo así.

Si es posible, ME GUSTARÍA GRAVEMENTE guardar TODOS los datos. Si no, entonces déjalo estar.


He pensado en la edición de la cadena de respuesta mediante programación, luego volver y tratar de re-análisis sintáctico se debe lanzar una excepción, pero he intentado algunos métodos y ninguno de ellos parecen éxito.

Gracias por su opinión.

Código es algo a lo largo de la línea de esta:

TextReader tr; 
XDocument doc; 

string   response; //XML string received from server. 
... 
tr = new StringReader (response); 

try 
{ 
    doc = XDocument.Load(tr); 
} 
catch (XmlException e) 
{ 
    //handle here? 
} 

Respuesta

11

XML puede manejar casi cualquier carácter, pero hay rangos, control codes and such, que no lo hará.

Su mejor opción, si no puede lograr que arreglen su salida, es desinfectar los datos en bruto que está recibiendo. Necesita reemplazar caracteres ilegales con el formato de referencia de caracteres que anotó.

(Ni siquiera se puede recurrir a CDATA, ya que no hay manera de escapar de estos personajes allí.)

0

Si su entrada no es XML, debe utilizar algo así como Tidy o Tagsoup para limpiar el lío.

Tomarían cualquier entrada e intentarían, con suerte, hacer un DOM útil a partir de ella.

No sé cómo se llaman las bibliotecas del lado oscuro.

9

¿Sería útil algo como se describe in this blog post?

Básicamente, crea una corriente de xml desinfectante.

+0

En realidad, está procesando un XML de una vez, como una cadena. –

+0

@Matthew, sí, ese es el ejemplo en el que él llama a .ReadToEnd(), pero podría simplemente usar .Read(), etc. Supongo que el OP tendrá que hacer lo que usted dijo. –

+0

Ese enlace fue extremadamente útil – Meiscooldude

0

Basura, Salida de basuras. Si la aplicación remota te está enviando basura, eso es todo lo que obtendrás. Si creen que envían XML, deben ser reparados. En este caso, no les está haciendo ningún favor al evitar su error.

También debe asegurarse de lo que ellos piensan que están enviando. ¿Qué significó el% 1C para ellos? ¿Qué querían que fuera?

+1

Ojalá estuviera en condiciones de corregir su error, pero no lo soy ... El error viene de la entrada del usuario sin filtro ... Algunos usuarios deciden poner algunos caracteres súper extraños allí ... y lo acepta. .. – Meiscooldude

+0

Mi recomendación sería rechazar la basura, luego producir un informe que muestre lo que se rechazó. A continuación, envíe ese informe al propietario del código de error, al menos una vez al mes. –

0

En mi humilde opinión la mejor solución sería modificar el código/programa/lo que produce el XML no válido que se está alimentando a su programa. Lamentablemente, esto no siempre es posible. En este caso, debe escapar de todos los caracteres < 0x20 antes de intentar cargar el documento.

0

Si realmente no puede corregir los datos XML fuente, considere tomar un enfoque como el que describí en this answer. Básicamente, creas una subclase TextReader (por ejemplo, StripTextReader) que envuelve un TextReader (tr) existente y descarta los caracteres no válidos.

+0

Su respuesta implica que los personajes realmente son basura. Que todo lo que tiene que hacer es descartarlos. Le sugerí que primero descubra qué deben ser esos personajes. –

14

Puede utilizar el XmlReader y establecer los XmlReaderSettings.CheckCharacters propiedad a falsa . Esto le permitirá leer el archivo XML a pesar de los caracteres no válidos. Desde allí, puede importar pasarlo a un objeto XmlDocument o XDocument.

Puedes leer un poco más sobre en mi blog.

Para cargar los datos a un System.Xml.Linq.XDocumentque se verá algo como esto:

XDocument xDocument = null; 
XmlReaderSettings xmlReaderSettings = new XmlReaderSettings { CheckCharacters = false }; 
using (XmlReader xmlReader = XmlReader.Create(filename, xmlReaderSettings)) 
{ 
    xmlReader.MoveToContent(); 
    xDocument = XDocument.Load(xmlReader); 
} 

Más información se puede encontrar here.

+2

** Enlaces relacionados en MSDN: ** [Propiedad XmlReaderSettings.CheckCharacters] (http://msdn.microsoft.com/en-us/library/system.xml.xmlreadersettings.checkcharacters%28v=vs.110%29.aspx) y [Método XmlReader.MoveToContent] (http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.movetocontent%28v=vs.110%29.aspx). – DavidRR

Cuestiones relacionadas