2012-06-27 16 views
9

¿Es factible en Java utilizar la API SAX para analizar una lista de fragmentos XML sin elemento raíz de una entrada de flujo?Analizar una lista de fragmentos XML sin elemento raíz de una entrada de flujo

he intentado analizar un XML tal, pero tiene un

org.xml.sax.SAXParseException: The markup in the document following the root element must be well-formed. 

antes de que se disparó hasta el evento endDocument.

Me gustaría no conformarme con soluciones obvias pero torpes como "preañadir un elemento raíz personalizado o utilizar el análisis de fragmentos almacenados en el búfer".

Estoy usando la SAX API estándar de Java 1.6. La fábrica de SAX había establecido Validación (falsa) en caso de que alguien se preguntara.

+0

Duplicado de http://stackoverflow.com/questions/3232110/parse-file-containing-xml-fragments-in-java. –

+0

Puede consultar [Resolviendo "El marcado en el documento que sigue al elemento raíz debe estar bien formado" Excepción] (http://opensourceforgeeks.blogspot.in/2015/01/resolving-markup-in-document-following.html) –

Respuesta

14

En primer lugar, y lo más importante de todo, el contenido que está analizando no es un documento XML. Desde el XML Specification:

[Definición:. Hay exactamente un elemento, llamado raíz o elemento de documento, ninguna parte de la cual aparece en el contenido de cualquier otro elemento]

ahora, en cuanto a analizar esto con SAX - a pesar de lo que ha dicho sobre la torpeza - me gustaría sugerir el siguiente enfoque:

Enumeration<InputStream> streams = Collections.enumeration(
    Arrays.asList(new InputStream[] { 
     new ByteArrayInputStream("<root>".getBytes()), 
     yourXmlLikeStream, 
     new ByteArrayInputStream("</root>".getBytes()), 
    })); 

SequenceInputStream seqStream = new SequenceInputStream(streams); 

// Now pass the `seqStream` into the SAX parser. 

Utilizando el SequenceInputStream es una forma conveniente de concatenar múltiples flujos de entrada en una sola transmisión. Se leerán en el orden en que se pasan al constructor (o en este caso, devuelto por el Enumeration).

Pásalo a tu analizador SAX, y listo.

+0

De acuerdo: el motivo para agregar un elemento raíz torpe es que se trata de datos torpes. De lo contrario, tan pronto como cierre cualquier elemento que sea el primer elemento que haya abierto, el analizador SAX creerá que ha finalizado, tal como lo hizo. También lo hago de esta manera para una secuencia de datos con formato XML similar a – Woody

+0

. Aunque proporcionaste una respuesta que ya he pensado, ¡la implementación es mucho más elegante de lo que podría pensar! Gracias por su respuesta. – yannisf

+3

Bueno, 'SequenceInputStream' es una de esas utilidades * olvidadas *, que nadie parece saber, a pesar de estar ahí desde Java 1.0. Solo quería recordar que aún está allí. :) – npe

Cuestiones relacionadas