2008-12-05 4 views
3

У меня есть полный каталог (~ 10 , 10) файлов XML, из которых мне нужно извлечь содержимое нескольких полей. Я тестировал разные синтаксические анализаторы xml, и поскольку мне не нужно проверять содержимое (дорого), я думал просто использовать xml.parsers.expat (самый быстрый) для прохождения файлов, один за другим, чтобы извлечь данные.Каков наиболее эффективный способ извлечения информации из большого количества xml-файлов в python?

  1. Есть ли более эффективный способ? (простое совпадение текста не работает)
  2. Нужно ли мне создавать новый ParserCreate() для каждого нового файла (или строки) или я могу повторно использовать его для каждого файла?
  3. Какие-либо оговорки?

Спасибо!

+0

Не можете найти более подробную информацию о файлах? Они идентичны? Все ли они содержат необходимую информацию? Почему текст не подходит? Пример или два тоже помогут. – muhuk 2008-12-05 20:04:26

+0

Какие еще парсеры вы пробовали? Для очень схожей цели я протестировал `xml.dom.ext.reader` и Python привязки libxml2 и libxml2 был намного быстрее. – bortzmeyer 2008-12-08 12:28:46

+0

@muhuk: соответствие текста бесполезно из-за специфических для XML вещей, например, поиск «foo» с совпадением текста не обнаружит «f o o», даже если это то же самое в XML. – bortzmeyer 2008-12-08 12:29:59

ответ

3

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

Но самое главное: вместо того, чтобы продумать несколько вариантов, просто реализуйте их и нарисуйте их на небольшом наборе. Это займет примерно столько же времени, и даст вам реальные цифры, которые будут двигаться вперед.

EDIT:

  • ли файлы на диске или сетевом диске локального? Сетевой ввод-вывод убьет вас здесь.
  • Проблема распараллеливается тривиально: вы можете разделить работу между несколькими компьютерами (или несколькими процессами на многоядерном компьютере).
1

Если вы знаете, что XML-файлы сгенерированы с использованием одного и того же алгоритма, возможно, было бы более эффективно вообще не выполнять синтаксический анализ XML. Например. если вы знаете, что данные находятся в строках 3, 4 и 5, вы можете прочитать файл по очереди, а затем использовать регулярные выражения.

Конечно, этот подход потерпит неудачу, если файлы не сгенерированы машиной или происходят из разных генераторов, или если генератор изменяется со временем. Тем не менее, я оптимист, что будет быть более эффективным.

Независимо от того, перерабатываете ли вы парсерные объекты, в значительной степени неактуальны. Будет создано еще много объектов, поэтому единственный объект парсера на самом деле не очень много.

1

Одна вещь, о которой вы не указали, - это то, читаете ли вы XML в DOM. Я предполагаю, что вы, вероятно, нет, но, если это случится, не делайте этого. Вместо этого используйте xml.sax. Использование SAX вместо DOM даст вам значительное повышение производительности.

4

Обычно я предлагаю использовать ElementTree iterparse или для сверхскоростной скорости, его аналог от lxml. Также попробуйте использовать Processing (поставляется с 2.6) для распараллеливания.

Важная вещь в отношении iterparse состоит в том, что вы получаете элементы (суб-) структур по мере их анализа.

import xml.etree.cElementTree as ET 
xml_it = ET.iterparse("some.xml") 
event, elem = xml_it.next() 

event всегда будет строка "end" в этом случае, но вы также можете инициализировать парсер также рассказать о новых элементах, как они обрабатываются. У вас нет гарантии, что все элементы-элементы будут проанализированы в этот момент, но атрибуты есть, если вас это интересует.

Еще один момент заключается в том, что вы можете прекратить чтение элементов с итератора раньше, то есть до того, как весь документ будет обработан.

Если файлы большие (являются ли они?), Существует общая идиома, позволяющая сохранить постоянное использование памяти так же, как в потоковом синтаксическом анализаторе.