Показ прогресса синтаксического анализатора XML Python при загрузке огромного файла

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

  •  05-07-2019
  •  | 
  •  

Вопрос

Я использую встроенный синтаксический анализатор XML Python для загрузки XML-файла размером 1,5 гигабайта, и это занимает целый день.

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

Мне нужно знать, как проникнуть внутрь этого процесса и измерить его прогресс, чтобы я мог показать индикатор выполнения.Любые идеи?

В minidom есть еще один метод, называемый parseString(), который возвращает дерево DOM, предполагая, что строка, которую вы передаете, является допустимым XML. Если бы я сам разбил файл на куски и передал их в parseString по одному, мог бы я объединить все Деревья DOM в конце снова вместе?

Это было полезно?

Решение

Вы используете, что вы используете Sax Sanger вместо DOM, DOM загружает все в память, Sax вместо этого выполняет строки по линии, и вы пишете обработчики для событий, так как вам нужно, чтобы это было эффективно, и вы сможете также написать индикатор прогресса.

Я также рекомендую попробовать парсер expat, это очень полезно.http://docs.python.org/library/pyexpat.html

для прогресса в использовании саксофона:

поскольку sax читает файл постепенно, вы можете обернуть передаваемый вами файловый объект своим собственным и отслеживать, сколько было прочитано.

редактировать:Мне также не нравится идея разделения файла сами и присоединиться к DOM в конце, таким образом, вам лучше писать свой собственный анализатор XML, я рекомендую вместо этого использовать Sax Parser, мне также интересно, какова ваша цель чтения файла концерта 1.5 в дереве DOM?похоже, саксофон здесь был бы лучше

Другие советы

Рассматривали ли вы использовать другие средства парсинга XML? Построение дерева таких больших XML-файлов всегда будет медленным и занимать много памяти. Если вам не нужно все дерево в памяти, анализ на основе потока будет намного быстрее. Это может быть немного сложным, если вы привыкли к манипулированию XML на основе дерева, но это окупится в виде огромного увеличения скорости (минуты вместо часов).

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

У меня есть нечто очень похожее для PyGTK, а не PyQt, использующего API pulldom. Он вызывается чуть-чуть за раз с использованием событий простоя Gtk (чтобы графический интерфейс не блокировался) и генераторов Python (чтобы сохранить состояние анализа).

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)

Слияние дерева в конце было бы довольно легко. Вы можете просто создать новый DOM и добавить к нему отдельные деревья по одному. Это дало бы вам достаточно точно настроенный контроль над ходом синтаксического анализа. Вы можете даже распараллелить его, если хотите, создавая разные процессы для анализа каждого раздела. Вам просто нужно убедиться, что вы разбили его разумно (не разбивая в середине тега и т. Д.).

scroll top