Mostra l'avanzamento del parser XML di Python durante il caricamento di un file di grandi dimensioni

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

  •  05-07-2019
  •  | 
  •  

Domanda

Sto usando il parser XML incorporato di Python per caricare un file XML da 1,5 gig e impiega tutto il giorno.

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

Devo sapere come entrare e misurare i suoi progressi in modo da poter mostrare una barra di avanzamento.  qualche idea?

minidom ha un altro metodo chiamato parseString () che restituisce un albero DOM assumendo che la stringa che passi sia XML valido, se dovessi dividere il file in blocchi e passarli a parseString uno alla volta, potrei forse unire nuovamente tutti gli alberi DOM alla fine?

È stato utile?

Soluzione

il tuo caso d'uso richiede l'uso di sax parser invece di dom, dom carica tutto in memoria, sax invece eseguirà l'analisi riga per riga e scrivi i gestori per gli eventi di cui hai bisogno quindi potrebbe essere efficace e si sarebbe in grado di scrivere anche l'indicatore di progresso

Raccomando anche di provare expat parser a volte è molto utile http://docs.python.org/library/pyexpat.html

per progressi usando sax:

mentre il sax legge il file in modo incrementale puoi avvolgere l'oggetto file che passi con il tuo e tenere traccia di quanto è stato letto.

modifica: Inoltre, non mi piace l'idea di dividere il file da soli e di unire DOM alla fine, in questo modo è meglio scrivere il proprio parser xml, consiglio invece di usare sax parser Mi chiedo anche quale sia il tuo scopo di leggere il file da 1,5 gig nell'albero DOM? sembra che il sax sarebbe meglio qui

Altri suggerimenti

Hai considerato di utilizzare altri mezzi per analizzare XML? Costruire un albero di file XML così grandi sarà sempre lento e dispendioso in termini di memoria. Se non hai bisogno dell'intero albero in memoria, l'analisi basata sul flusso sarà molto più veloce. Può essere un po 'scoraggiante se sei abituato alla manipolazione XML basata su alberi, ma pagherà sotto forma di un enorme aumento di velocità (minuti anziché ore).

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

Ho qualcosa di molto simile per PyGTK, non PyQt, usando l'API pulldom. Viene chiamato un po 'alla volta usando gli eventi inattivi di Gtk (quindi la GUI non si blocca) e i generatori Python (per salvare lo stato di analisi).

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)

Unire l'albero alla fine sarebbe abbastanza facile. Potresti semplicemente creare un nuovo DOM e fondamentalmente aggiungere i singoli alberi ad uno ad uno. Questo ti darebbe un controllo abbastanza finemente regolato sull'andamento dell'analisi. Si potrebbe anche parallelizzare se si desidera generando processi diversi per analizzare ciascuna sezione. Devi solo assicurarti di dividerlo in modo intelligente (non dividere nel mezzo di un tag, ecc.).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top