Estoy trabajando en una aplicación, y mi trabajo solo consiste en desarrollar una interfaz de Python de ejemplo para la aplicación. La aplicación puede proporcionar documentos basados en XML, puedo obtener el documento a través del método HTTP Get, pero el problema es que el documento basado en XML es interminable, lo que significa que no habrá un elemento final. Sé que el documento debería ser manejado por SAX, pero ¿cómo lidiar con el problema sin fin? ¿Alguna idea, código de muestra?python handle XML sin fin
Respuesta
Si el documento nunca obtiene una etiqueta de cierre para un elemento en el documento, entonces no se forma correctamente XML, lo que causará estragos en cualquier analizador XML.
Dicho esto, usar Python SAX2 API parece ser el mejor enfoque, pero tendrá que determinar qué excepción arrojará la etiqueta cercana faltante, atraparla y manejarla usted mismo.
Agregado
por hecho que está recibiendo un documento XML como esto:
<? xml version="1.0" ?>
<foo>
<bar>...</bar>
<bar>...</bar>
<bar>...</bar>
<bar>...</bar>
...
Y nunca recibirá un cierre </foo>
. En este caso, un analizador SAX que está reaccionando a los elementos bar
emitirá una secuencia de eventos para startElement(bar)
y endElement(bar)
. Presumiblemente, reunirá todos los datos entre el inicio y el final, y luego procesará todo de una vez que vea el evento final.
La única manera de detener este ciclo va a ser a través de la acción exterior: definir de antemano el número de bar
elementos para procesar, o definir de antemano la cantidad de tiempo que quieres dedicar a recibir bar
eventos. Ejecute el analizador SAX en un hilo y luego elimine el hilo cuando llegue a su límite. Querrá que su proceso principal duerma mientras espera que el subproceso sax-parser finalice.
No esperaría una excepción: el punto es que la secuencia XML no tiene EOF, por lo que no hay una condición de error. –
Tome una mirada en el módulo de xmlstream en jabberpy (también disponible de twisted):
xmlstream.py proporciona una funcionalidad simple para la implementación de protocolos de red basados secuencia XML. Se utiliza como base para jabber.py.
xmlstream.py gestiona la conectividad de red y el análisis xml de la transmisión. Cuando se analiza un 'elemento de protocolo' completo (es decir, un hijo completo de la raíz xmlstreams), se llama al método dipatch con una instancia 'Node' de esta estructura. La clase Node es una clase XML DOM muy simple para manipulando documentos XML o 'elementos de protocolo' en este caso .
Supongo que su XML es básicamente una lista de elementos XML idénticos reunidos en un solo contenedor. Algo así como
<items>
<item>
<!-- content here -->
</item>
<item>
<!-- content here -->
</item>
<item>
<!-- content here -->
</item>
</items>
En SAX cuando el analizador se pone y el evento final, se puede analizar el tema completado, desactive la pila, y pasar el tema relativo a cualquier otro tipo de código se debe manipular artículos analizados.
def process(item) :
# App logic goes here
class ItemsHandler(xml.sax.handler.ContentHandler) :
# Omitting __init__, startElement, and characters methods
# to store data on a stack during processing
def endElement(self, name) :
if name == "item" :
# create item from stored data on stack
parsed_item = self.parse_item_from_stack()
process(parsed_item)
Si la lógica de la aplicación es bastante complicada, se le quiere poner el SAX analizar en un hilo separado para que no se pierda los eventos.
Si el documento es interminable, ¿por qué no agregar la etiqueta final (del elemento principal) manualmente antes de abrirla en el analizador? No sé Python, pero ¿por qué no agregar </endtag>
a la cadena?
Simplemente: porque no hay un final de tal documento. Por lo tanto, no puede "agregar' 'al final". – arilou
No puedo proporcionar una solución en Python de inmediato, pero le daré una pista.
Ese tipo de análisis XML es manejado por analizadores StAX. El problema aquí es que un analizador SAX impulsa eventos, pero StAX proporciona una interfaz para extraer eventos. StAX se usa principalmente para el análisis parcial de XML (analizando únicamente los encabezados de un mensaje SOAP), y este parece ser su caso.
No he visto un analizador tipo StAX en la biblioteca estándar de Python, pero definitivamente debe haber uno.
UPD: lxml (como un contenedor tp libxml2) parece tener similar functinality.
Esto es lo que yo uso para analizar una secuencia XML sin fin que llegue desde un equipo remoto (en mi caso me conecto a través de una toma de corriente y uso socket.makefile ('r') para crear el objeto de archivo)
19.12.2. IncrementalParser Objects
parser = xml.sax.make_parser(['xml.sax.IncrementalParser'])
handler = FooHandler()
parser.setContentHandler(handler)
data = sockfile.readline()
while (len(data) != 0):
parser.feed(data)
data = sockfilefile.readline()
De hecho, no hay ningún símbolo como 'xml.sax.IncrementalParser' y' make_parser' espera una lista de módulos que tienen la función 'create_parser'. Hay 'xml.sax.xmlreader.IncrementalParser', pero no implementa' feed', siendo solo una interfaz. Afortunadamente, el módulo del analizador predeterminado, 'xml.sax.expatreader', que' make_parser' intenta cargar después de que no pudo cargar los módulos proporcionados por el usuario, implementa 'xml.sax.xmlreader.IncrementalParser'. Entonces es suficiente llamar a 'make_parse' sin un argumento. – saaj
puede utilizar la función de la iterparse
xml.etree.ElementTree
(o cElementTree
para la velocidad) en el stdlib. (También se puede utilizar lxml
)
El truco se describe aquí: http://effbot.org/zone/element-iterparse.htm#incremental-parsing
El ejemplo describe exactamente lo que necesita. No menciona nada sobre archivos sin fin, pero funcionará. (continuará funcionando). Lo más importante: no te olvides de borrar el elemento raíz.
fácil y disponible en el stdlib ;-)
- 1. carpa sin fin
- 2. sin fin ViewPager androide
- 3. Marcador jQuery horizontal sin fin
- 4. Cambio clave de la matriz sin fin
- 5. Implementar desplazamiento sin fin en ListView
- 6. NSScrollView infinite/scroll sin fin | subview reuse
- 7. ¿Hay bucles sin fin en mal estado?
- 8. bytes sin fin inesperado para un bucle
- 9. Python Ordenar Collections.DefaultDict con el fin
- 10. Android Handle phone call
- 11. Handle Push Notifications
- 12. org.xml.sax.SAXParseException: fin de archivo prematuro para * VÁLIDO * XML
- 13. Método sin bloqueo para analizar XML en python
- 14. Thread ID vs. Thread Handle
- 15. ¿Cómo reenvío declarar HANDLE? (Win32)
- 16. Xml Serialización sin eliminación
- 17. Spring AOP sin XML
- 18. ¿Cómo implementar una galería sin fin en Android?
- 19. ¿Cómo detener el temporizador EJB 3 sin fin?
- 20. Bucle sin fin en un servlet - ¿es posible la recuperación?
- 21. ¿Por qué Xcode crea recursividad de carpetas sin fin?
- 22. ¿Cómo hacer un control deslizante img deslizante sin fin?
- 23. Argumentos del método sin fin del mismo tipo
- 24. Efecto de "desplazamiento sin fin" en una tabla HTML
- 25. Python XML Parsing
- 26. Crunching xml with python
- 27. Python BeautifulSoup XML Parsing
- 28. Pan Gesto Fin
- 29. ImportError: Sin módulo denominado - Python
- 30. Proceso de ejecución dado el proceso handle
suena como una buena oportunidad para explorar generadores de Python. –