Mostrando progresso do parser XML de python ao carregar um arquivo grande
Pergunta
Im usando Python construído em parser XML para carregar um arquivo XML 1.5 show e leva todo o dia.
from xml.dom import minidom
xmldoc = minidom.parse('events.xml')
Eu preciso saber como obter dentro daquele e medir seu progresso para que eu possa mostrar uma barra de progresso. quaisquer ideias?
minidom tem outro método chamado parseString () que retorna uma árvore DOM assumindo a seqüência que você passá-lo é um XML válido, Se eu fosse para dividir o arquivo me em pedaços e passá-las para parseString um de cada vez, eu poderia mesclar todas as árvores DOM volta juntos no final?
Solução
Você usecase exige que você use analisador SAX em vez de dom, cargas dom tudo na memória, sax vez vai fazer linha por linha de análise e você escrever manipuladores para eventos como você precisa assim poderia ser eficaz e você seria capaz de indicador de progresso de gravação também
Eu também recomendo tentar analisador expatriados em algum momento ele é muito útil http://docs.python.org/library/pyexpat.html
para o progresso usando sax:
como sax lê arquivo de forma incremental pode embrulhar o objeto de arquivo que você passa com seu próprio e manter o controle de quanto foram lidas.
edit: Eu também não gosto de idéia de vós arquivo dividindo e juntando DOM no final, de que maneira você está escrevendo melhor o seu próprio analisador xml, eu recomendo em vez de usar analisador SAX Gostaria também de saber qual o seu propósito de ler o arquivo de 1,5 gig na árvore DOM? olhada como sax seria melhor aqui
Outras dicas
Será que você considerar usar outros meios de análise de XML? Construir uma árvore de tais grandes arquivos XML será sempre lento e intensivo de memória. Se você não precisa de toda a árvore na memória, fluxo de análise baseada será muito mais rápido. Pode ser um pouco assustador se você está acostumado a árvore com base manipulação XML, mas ele vai pagar de na forma de um aumento enorme velocidade (minutos em vez de horas).
Eu tenho algo muito semelhante para PyGTK, não PyQt, usando a API pulldom. Ele é chamado um pouco de cada vez usando eventos ociosas Gtk (para que a GUI não lock up) e geradores de Python (para salvar o estado de análise).
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)
A fusão da árvore no final seria muito fácil. Você poderia simplesmente criar um novo DOM, e, basicamente, anexar as árvores individuais a ele um por um. Isto lhe daria o controle muito afinado sobre o andamento da análise também. Você poderia até mesmo paralelizar-lo se você queria por desova processos diferentes para analisar cada seção. Você apenas tem que certificar-se de que você dividi-lo de forma inteligente (não rachar no meio de uma tag, etc.).