read leer from ejemplo array c# xml .net-4.0 xml-parsing xmlreader

c# - leer - xmlreader genexus



analizar fragmentos XML casi formados: cómo omitir varios encabezados XML (3)

Estoy obligado a escribir una herramienta que pueda manejar el siguiente fragmento de XML que no está bien formado, ya que contiene declaraciones XML en el medio de la transmisión.

La compañía ya tiene estos archivos de tipo en uso durante mucho tiempo, por lo que no hay ninguna opción para cambiar el formato.

No hay un código fuente disponible que realice el análisis sintáctico, y la plataforma elegida para las nuevas herramientas es .NET 4 o superior, preferiblemente con C #.

Así es como se ven los fragmentos:

<Header> <Version>1</Version> </Header> <Entry><?xml version="1.0"?><Detail>...snip...</Detail></Entry> <Entry><?xml version="1.0"?><Detail>...snip...</Detail></Entry> <Entry><?xml version="1.0"?><Detail>...snip...</Detail></Entry> <Entry><?xml version="1.0"?><Detail>...snip...</Detail></Entry>

Usando un XmlReader con el XmlReaderSettings.ConformanceLevel establecido en ConformanceLevel.Fragment , puedo leer el elemento <Header> completo fine. Incluso el inicio del elemento <Entry> está bien, sin embargo, al leer la información <Detail> XmlReader arroja una XmlException , como se lee en la declaración XML <?xml...?> Xml <?xml...?> Que no espera en ese lugar.

¿Qué opciones tengo para omitir esas declaraciones XML, además de pesadas manipulaciones de cadenas?

Como los fragmentos pueden ir fácilmente por encima de 100 megabytes por pieza, prefiero no cargar todo en la memoria de una vez. Pero eso es lo que se necesita, estoy abierto para eso.

Ejemplo de las excepciones que recibo:

System.Xml.XmlException: Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it. Line ##, position ##.


No creo que las clases integradas ayuden; probablemente tengas que hacer un cierto preparsing y eliminar los encabezados adicionales. Si su muestra es precisa, puede hacer una string.Replace(badXml, "<?xml version=/"1.0/"?>, "") Y string.Replace(badXml, "<?xml version=/"1.0/"?>, "") su camino.


Si no está seguro de que las declaraciones permanezcan iguales todo el tiempo, reemplace <?xml <XmlDeclaration con <XmlDeclaration y ?> Con /> y use un analizador regular;)

Además, ¿ha intentado pasar los archivos a través de un programa de estilo ordenado XML?

También puede haber una biblioteca SGML que puede usar para preprocesar los datos y generar el XML correcto.


Agregué esto como una respuesta porque conserva el resaltado de sintaxis.

private void ProcessFile(string inputFileName, string outputFileName) { using (StreamReader reader = new StreamReader(inputFileName, new UTF8Encoding(false, true))) { using (StreamWriter writer = new StreamWriter(outputFileName, false, Encoding.UTF8)) { string line; while ((line = reader.ReadLine()) != null) { const string xmlDeclarationStart = "<?xml"; const string xmlDeclarationFinish = "?>"; if (line.Contains(xmlDeclarationStart)) { string newLine = line.Substring(0, line.IndexOf(xmlDeclarationStart)); int endPosition = line.IndexOf(xmlDeclarationFinish, line.IndexOf(xmlDeclarationStart)); if (endPosition == -1) { throw new NotImplementedException(string.Format("Implementation assumption is wrong. {0} .. {1} spans multiple lines (or input file is severely misformed)", xmlDeclarationStart, xmlDeclarationFinish)); } // the code completely strips the <?xml ... ?> part // an alternative would be to make this a new XML element containing // the information inside the <?xml ... ?> part as attributes // just like Daren Thomas suggested newLine += line.Substring(endPosition + 2); line = newLine; } writer.WriteLine(line); } } } }