Affichage de la progression de l'analyseur XML de python lors du chargement d'un fichier volumineux

StackOverflow https://stackoverflow.com/questions/1001871

  •  05-07-2019
  •  | 
  •  

Question

J'utilise l'analyseur XML intégré de Python pour charger un fichier XML de 1,5 Go, et cela prend toute la journée.

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

J'ai besoin de savoir comment y entrer et en mesurer la progression afin de pouvoir afficher une barre de progression.  des idées?

minidom a une autre méthode appelée parseString () qui renvoie une arborescence DOM en supposant que la chaîne transmise est valide, si je divisais le fichier moi-même en morceaux et les transmettais à parseString un par un, puis-je éventuellement fusionner tous les arbres DOM à la fin?

Était-ce utile?

La solution

votre cas d'utilisation nécessite que vous utilisiez un analyseur syntaxique au lieu de dom, dom charge tout en mémoire, sax effectuera une analyse ligne par ligne et vous rédigerez des gestionnaires d'événements en fonction de vos besoins. donc pourrait être efficace et vous seriez capable d'écrire un indicateur de progrès aussi

Je recommande aussi d'essayer Expat Parser de temps en temps c'est très utile http://docs.python.org/library/pyexpat.html

pour progresser en utilisant sax:

pendant que sax lit le fichier progressivement, vous pouvez envelopper le fichier objet que vous transmettez avec le vôtre et garder une trace du nombre de lectures.

modifier: Je n'aime pas non plus l'idée de scinder le fichier vous-même et de rejoindre DOM à la fin. De cette façon, vous feriez mieux d'écrire votre propre analyseur XML, je recommande d'utiliser plutôt l'analyseur sax. Je me demande également à quoi sert votre objectif de lire un fichier de 1,5 Go dans l’arborescence DOM? ressembler à du sax serait mieux ici

Autres conseils

Avez-vous envisagé d’utiliser d’autres moyens d’analyser XML? Construire une arborescence de si gros fichiers XML sera toujours lent et nécessitera beaucoup de mémoire. Si vous n’avez pas besoin de l’arbre complet en mémoire, l’analyse basée sur les flux sera beaucoup plus rapide. Cela peut être un peu décourageant si vous êtes habitué à la manipulation XML basée sur une arborescence, mais cela vous rapportera une augmentation considérable de la vitesse (minutes au lieu de plusieurs heures).

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

J'ai quelque chose de très similaire pour PyGTK, pas PyQt, en utilisant l’API pulldom. Il est appelé petit à petit à l'aide d'événements inactifs Gtk (pour que l'interface graphique ne se verrouille pas) et de générateurs Python (pour enregistrer l'état d'analyse).

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)

La fusion de l’arbre à la fin serait assez facile. Vous pouvez simplement créer un nouveau DOM et y ajouter les arbres individuels un par un. Cela vous donnerait également un contrôle assez fin sur la progression de l'analyse. Vous pouvez même la mettre en parallèle si vous souhaitez générer différents processus pour analyser chaque section. Vous devez simplement vous assurer de la scinder intelligemment (ne pas scinder au milieu d'une balise, etc.).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top