парсер большого xml приблизительно 300 мб

pilot911

Новичок
неужели нет бинарных инструментов для парсинга и конвертации структуры в sql запрос ?
 

vovanium

Новичок
pilot911
неужели нет бинарных инструментов для парсинга
Ну вроде в MySQL 6 добавили LOAD XML (аналог LOAD DATA), но 6-ку пока не ставил. А у большинства подобных парсеров проблема с размерами обычно, люди не подозревают что бывают xml'ки метров по 300-500 :)
 

crocodile2u

http://vbolshov.org.ru
Когда пришлось делать что-то подобное, я договорился о поставках исходного XML в ZIP-архиве и потом при разборе использовал ZipArchive + XmlReader. На разбор и импорт в БД 2Gb XML уходило около 15 минут, по-моему. Правда, не помню, на каком железе. Это, собсно, совет: если есть возможность, забирайте XML в архиве, уменьшите трафик, ну и скорость, соответственно, вырастет.
 

Активист

Активист
Команда форума
Автор оригинала: vovanium
ок, т.е. xml в котором вся инфа в тегах без параметров.
$n++ в принципе не особо интересно, так как в данном случае нужно сформировать из xml набор строк для загрузки в базу.
Я для теста сделал xml'ку, экспортнул таблицу с помощью phpmyadmin, получилась xml'ка 595 МБ (в файле немного больше 16 млн. строк).
Формат типа
Код:
<db>
  <table>
    <field1>Поле 1</field1>
    <field2>Поле 2</field2>
    <field_n>Поле N</field_n>
  </table>
  <table>
    <field1>Поле 1</field1>
    <field2>Поле 2</field2>
    <field_n>Поле N</field_n>
  </table>
</db>
xml_parser c пустыми функциями startElement, endElement, обрабатывает файл за 99 сек

Банальное построчное чтение с помощью
PHP:
while(fgets($x)) {}
выполняется 7 сек.

простенький парсер на чистом php который вырезает теги одной записи, т.е. то что между <table></table>, обрабатывает файл за 6,5 сек., если еще добавить преобразование этих строк в строки разделенные табуляцией (для быстрого заливания с помощью LOAD DATA), время возрастает до 9,5 сек.

В общем что и требовалось доказать, проблема этих событийных парсеров, что событий очень много в моем случае было 650 тысяч записей в бд, а xml тегов получилось больше 16 млн., учитывая что на каждый тег 2 события, получится 32 млн. вызовов функций.

На перле не пробовал пока, на этом компе не установлен, как-нибудь позже. Но быстрее работает он скорее всего только за счет другой реализации, во-первых, сам файл передается как параметр в объект, и его читает уже сам модуль, нет лишнего тягания данных, во-вторых, в парсер ты передаешь только один хендлер, а в php обязательно 2, так что вполне возможно perl экономит время на запусках закрывающего хендлера.
Очень интересно посмотреть на код :)
 

vovanium

Новичок
Очень интересно посмотреть на код
Ну готовый код все-таки давать наверное не буду, не буду лишать народ возможности поэксперименировать.
- Читаем
- Находим нужный открывающий тег в нашем случае <table>
- Находим закрывающий тег для записи
- Преобразовываем вырезанную запись в запись разделенную табами (по сути самое рессурсоемкое) попробовал 4 варианта, разброс времени от 9,5 до 34 сек

P.S. По перлу протестил, получается количество открывающих тегов подсчитывает за 35 сек, но если добавить еще пустую функцию на закрывающий время увеличивается до 47 секунд.
И в perl и в php эти модули это лишь интерфес для сишного библиотек, но вот в perl похоже к Expat, а в php возможны два варианта, Expat или libXML, у меня libXML
 

A1x

Новичок
а как-то обрабатывается ситуация с тегом если например один fread прочитал только "....<ta" а следующий "ble> ..."?

fread же каждый раз читает кусок фиксированной длины, а длина содержимого поля в общем случае неизвестна
 

vovanium

Новичок
один fread прочитал только
fread'ом читаешь строку фиксированной длины потом пробегаешься по строке strpos, нашел один закрывающий тег, вырезал содержимое, потом продолжаешь с позиции на которой остановился, если ты прошелся всю строку и не нашел закрывающий тег, значит нужно делать следующий fread, добавляешь его к остатку строки, и продолжаешь дальше.
 

SiMM

Новичок
< и >, в принципе, в валидном XML запрещены (начало тэга можно искать по "<")... за исключениям использования оных в CDATA.
 
Сверху