Estoy usando el analizador XML incorporado de Python para cargar un archivo XML de 1.5 gig y me lleva todo el día.

from xml.dom import minidom
xmldoc = minidom.parse('events.xml')

Necesito saber cómo entrar y medir su progreso para poder mostrar una barra de progreso. ¿algunas ideas?

Minidom tiene otro método llamado parseString () que devuelve un árbol DOM asumiendo que la cadena que pasa es XML válido. Si tuviera que dividir el archivo en trozos y pasarlos a parseString uno a la vez, ¿podría fusionar todos los ¿Los árboles DOM vuelven a estar juntos al final?

3
Nathan 16 jun. 2009 a las 18:32

4 respuestas

La mejor respuesta

Si usa case, debe usar sax parser en lugar de dom, dom carga todo en la memoria, sax en su lugar realizará un análisis de línea por línea y escribirá controladores para eventos según lo necesite, por lo que podría ser eficaz y también podría escribir un indicador de progreso

También recomiendo probar el analizador de expatriados en algún momento, es muy útil http://docs.python.org/library/pyexpat.html

Para progresar usando sax:

Como el saxo lee el archivo de forma incremental, puede ajustar el objeto de archivo que pasa con el suyo y realizar un seguimiento de la cantidad que se ha leído.

Editar: tampoco me gusta la idea de dividir el archivo y unirse al DOM al final, de esa manera es mejor escribir su propio analizador xml, recomiendo en su lugar usar el analizador sax. También me pregunto cuál es su propósito de leer el archivo 1.5 gig en el árbol DOM ? parece saxo sería mejor aquí

5
Anurag Uniyal 16 jun. 2009 a las 15:24

Tengo algo muy similar para PyGTK, no PyQt, usando la API de Pulldom. Se llama poco a poco usando eventos inactivos Gtk (para que la GUI no se bloquee) y generadores Python (para guardar el estado de análisis).

def idle_handler (fn):
  fh = open (fn)  # file handle
  doc = xml.dom.pulldom.parse (fh)
  fsize = os.stat (fn)[stat.ST_SIZE]
  position = 0

  for event, node in doc:
    if position != fh.tell ():
      position = fh.tell ()
      # update status: position * 100 / fsize

    if event == ....

    yield True   # idle handler stays until False is returned

 yield False

def main:
  add_idle_handler (idle_handler, filename)
3
eduffy 16 jun. 2009 a las 15:09

Fusionar el árbol al final sería bastante fácil. Simplemente podría crear un nuevo DOM y básicamente agregarle los árboles individuales uno por uno. Esto también le daría un control muy bien ajustado sobre el progreso del análisis. Incluso podría paralelizarlo si lo desea al generar diferentes procesos para analizar cada sección. Solo tiene que asegurarse de dividirlo de manera inteligente (sin dividir en el medio de una etiqueta, etc.).

2
Dan Lorenc 16 jun. 2009 a las 14:35

¿Consideró utilizar otros medios para analizar XML? Construir un árbol de archivos XML tan grandes siempre será lento y requerirá mucha memoria. Si no necesita todo el árbol en la memoria, el análisis basado en secuencias será mucho más rápido. Puede ser un poco desalentador si está acostumbrado a la manipulación XML basada en árboles, pero pagará en forma de un gran aumento de velocidad (minutos en lugar de horas).

http://docs.python.org/library/xml.sax.html

5
Benjamin Wohlwend 16 jun. 2009 a las 14:57