У меня есть большой файл данных XML (> 160M) для обработки, и кажется, что синтаксический анализ SAX/expat/pulldom - это то, что нужно. Я хотел бы иметь поток, который просеивает узлы и помещает узлы для обработки в очередь, а затем другие рабочие потоки извлекают из очереди следующий доступный узел и обрабатывают его.
У меня есть следующее (у него должны быть замки, я знаю - это будет позже)
import sys, time
import xml.parsers.expat
import threading
q = []
def start_handler(name, attrs):
q.append(name)
def do_expat():
p = xml.parsers.expat.ParserCreate()
p.StartElementHandler = start_handler
p.buffer_text = True
print("opening {0}".format(sys.argv[1]))
with open(sys.argv[1]) as f:
print("file is open")
p.ParseFile(f)
print("parsing complete")
t = threading.Thread(group=None, target=do_expat)
t.start()
while True:
print(q)
time.sleep(1)
Проблема в том, что тело блока while
вызывается только один раз, и тогда я даже не могу его прервать ctrl-C. В файлах меньшего размера вывод соответствует ожидаемому, но это, по-видимому, указывает на то, что обработчик вызывается только тогда, когда документ полностью проанализирован, что, по-видимому, противоречит цели синтаксического анализатора SAX.
Я уверен, что это мое собственное невежество, но я не понимаю, где я делаю ошибку.
PS: я также пытался изменить start_handler
таким образом:
def start_handler(name, attrs):
def app():
q.append(name)
u = threading.Thread(group=None, target=app)
u.start()
Хотя любви нет.