Analice varias declaraciones XML en un solo archivo mediante lxml.etree.iterparse

Necesito analizar un archivo que contenga varios archivos XML, es decir, … y así sucesivamente. Al usar etree.iterparse, obtengo el siguiente error (correcto):

lxml.etree.XMLSyntaxError: XML declaration allowed only at the start of the document 

Ahora, puedo preprocesar el archivo de entrada y producir para cada archivo XML contenido un archivo separado. Esta podría ser la solución más fácil. Pero me pregunto si existe una solución adecuada para este “problema”.

¡Gracias!

Los datos de muestra que ha proporcionado sugieren un problema, mientras que la pregunta y la excepción que ha proporcionado sugieren otro. ¿Tiene varios documentos XML concatenados, cada uno con su propia statement XML, o tiene un fragmento XML con varios elementos de nivel superior?

Si es el primero, entonces la solución implicará dividir el flujo de entrada en múltiples flujos y analizar cada uno individualmente. Esto no significa necesariamente, como sugiere un comentario, implementar un analizador XML. Puede buscar declaraciones XML en una cadena sin tener que analizar nada más en ella, siempre que su entrada no incluya secciones CDATA que contengan declaraciones XML sin escapar. Puede escribir un objeto similar a un archivo que devuelve caracteres de la secuencia subyacente hasta que llegue a una statement XML, y luego envuélvalo en una función de generador que continúe devolviendo secuencias hasta que se scope EOF. No es trivial, pero tampoco es muy difícil.

Si tiene un fragmento XML con varios elementos de nivel superior, puede simplemente envolverlos en un elemento XML y analizar todo.

Por supuesto, como con la mayoría de los problemas que involucran una entrada XML incorrecta, la solución más sencilla puede ser arreglar lo que está produciendo la entrada incorrecta.

Utilicé expresiones regulares para resolver este problema. Supongamos que los datos son una cadena que contiene sus múltiples documentos xml y que el manejador es una función que hará algo con cada documento. Después de ejecutar este bucle, los datos estarán vacíos o contendrán un documento XML incompleto, y la función de manejar se habrá llamado cero o más veces.

 while True: match = re.match (r''' \s* # ignore leading whitespace ( # start first group <(?P\S+).*?> # opening tag (with optional attributes) .*? # stuff in the middle  # closing tag ) # end of first xml document (?P.*) # anything else ''', data, re.DOTALL | re.VERBOSE) if not match: break document = match.group (1) handle (document) data = match.group ('REM')