Василий Г.
101 сообщение
#14 лет назад
Возникла необходимость парсить xml файл и данные добавлять в БД.
Но файл весит 600 метров.
Скрипт врядли сможет его обработать, т.к. на хостинге ставят ограниечение на выплнение скриптов.
Как в таком случае быть?
Вадим Т.
3240 сообщений
#14 лет назад
Если такую операцию будет нужно периодически делать на хосте, то вот вариант реализации:

1. Разбить этот огромный XML файл на несколько сотен мелких файлов (написать отдельную программу для этого).
2. Затем эти мелкие файлы обрабатывать поочередно, скорее всего для этого придется делать несколько вызовов (реализовать очередь).

Если же это разовая операция, то вполне можно скачать файл на локальный комп, локально же распарсить (уже без ограничений), сохранить в локальную БД, сделать дамп сохраненных данных, и потом залить этот дамп в БД на хосте.
Андрей М.
295 сообщений
#14 лет назад
Смотря как xml структурирован.. Я к примеру резал на куски построчно.. Единственное, разрез может пройтись поперек тега, что создает некоторые трудности.
Евгений Б.
5330 сообщений
#14 лет назад
Цитата ("andrew-projects"):
я к примеру резал на куски построчно..

если можно построчно, значит можно и просто побайтно в потоке читать.
Владимир А.
246 сообщений
#14 лет назад
XMl построчно в общем случае бить нельзя, т.к. на выходе нельзя гарантировать правильную обработку. Это одна из ключевых проблем данного формата.

Для этих целей нужна отдельная прога, которая разобьет документ на отдельные файлы без потери общей сущности.
Роман Беляев
16382 сообщения
#14 лет назад
Надо смотреть что за структура. Если что-то не сложное и не запутанное - вроде описаний товаров и категорий, то наверняка поделится на части без проблем.
Василий С.
402 сообщения
#14 лет назад
Что если увеличить время выполнения скрипта: set_time_limit(секунды)?
Олег Казакевич
702 сообщения
#14 лет назад
Что-то я совсем не понимаю ничего. А SAX для чего вообще тогда ?
Дмитрий Л.
52 сообщения
#14 лет назад
Можно как-нибудь так:
$reader = new XMLReader();

$reader->open($cfg);
if (!$reader->isValid()) {
finish("Error occured - invalid xml\n");
}

while ($reader->read()) {
if (XMLReader::ELEMENT == $reader->nodeType) {
switch ($reader->localName) {
....

XMLReader работает по тому же принципу, что и вышеупомянутый SAX, отсюда довольно высокая скорость работы и малое потребление памяти
Евгений О.
2989 сообщений
#14 лет назад
В PHP есть такая библитека "XML Parser Functions". Для работы не слишком удобна, но, насколько я знаю, там вообще нет ограничений по размеру файла.

PS У меня эти функции разбирают xml-файл 300МБ без проблем.
Вадим Т.
3240 сообщений
#14 лет назад
Цитата ("okman"):
Что-то я совсем не понимаю ничего. А SAX для чего вообще тогда ?

SAX (или XMLReader) тут сам по себе не очень поможет, так как маловероятно, что получится распарсить XML 600 мб в рамках ограниченного лимита времени на хостинге (обычно на шаред хостингах лимит 30-60 секунд). Не говоря уже о том, чтобы положить распарсенные данные в БД, тут уж тем более будет проблема с лимитами. На хостинге по частям этот файл обрабатывать придется.

Кстати, я подумал, можно и не создавать кучу мелких файлов. Но придется сделать свой парсер, который будет принимать в качестве параметра позицию в файле, и при каждом следующем запуске будет начинать парсинг файла с этой позиции, затем сохраняя где-либо (в файле или БД) новую текущую позицию для следующего запуска. Этот способ позволит экономить место, так как разбивать на мелкие файлы будет не нужно.
Сергей Шпак
596 сообщений
#14 лет назад
DiamondPhoenix, наверное по этому проекту : , угадал ?
Николай Т.
205 сообщений
#14 лет назад
Цитата ("DiamondPhoenix"):
Возникла необходимость парсить xml файл и данные добавлять в БД.
Но файл весит 600 метров.
Скрипт врядли сможет его обработать, т.к. на хостинге ставят ограниечение на выплнение скриптов.
Как в таком случае быть?

Читать построчно + анализировать открывающий - закрывающий тег