Разбиение на части длинного парсинга XML

Темы, не касающиеся фреймворка, но относящиеся к программированию в целом.
Ответить
Аватара пользователя
porcelanosa
Сообщения: 570
Зарегистрирован: 2010.03.16, 04:31
Откуда: Москва

Разбиение на части длинного парсинга XML

Сообщение porcelanosa »

БОльшой XML
Надо распарсить на сервере.
Можно отключить ограничение на время выполнения.
Но на локальной машине это занимает 20-30 минут и 200-300 мегабайт памяти.
Сервер обычный виртуальный хостинг.
Как разбить на части выполнение этой задачи?
Подскажите в каком направлении копать?
mcintosh-club.ru - первый мой сайт с использование Yii //
Акустика Sonus Faber Hi-End класса//
Необрезная доска и другие пиломатериалы
Аватара пользователя
rugabarbo
Сообщения: 1063
Зарегистрирован: 2015.06.21, 16:21
Контактная информация:

Re: Разбиение на части длинного парсинга XML

Сообщение rugabarbo »

Нашёл статью, которую хотел скинуть вместо дока: http://instanceof.org/xmlreader-simplexml-example/

Суть в том, что вы перемещаетесь по узлам огромного файла с помощью XMLReader, а каждый отдельный узел загружаете в память с помощью SimpleXML. Это чуть более простой подход, нежели использование чистого XMLReader - вам не придётся вручную парсить внутренности каждого отдельного узла.
Аватара пользователя
porcelanosa
Сообщения: 570
Зарегистрирован: 2010.03.16, 04:31
Откуда: Москва

Re: Разбиение на части длинного парсинга XML

Сообщение porcelanosa »

как парсить понятно.
узлы маленькие.
Но их много.
т.е. разбить на части смысла нет.
mcintosh-club.ru - первый мой сайт с использование Yii //
Акустика Sonus Faber Hi-End класса//
Необрезная доска и другие пиломатериалы
Аватара пользователя
rugabarbo
Сообщения: 1063
Зарегистрирован: 2015.06.21, 16:21
Контактная информация:

Re: Разбиение на части длинного парсинга XML

Сообщение rugabarbo »

Выше статью скинул, предугадав ваш вопрос. Парсить отдельные узлы не придётся - вы загрузите их в SimpleXML.
Аватара пользователя
porcelanosa
Сообщения: 570
Зарегистрирован: 2010.03.16, 04:31
Откуда: Москва

Re: Разбиение на части длинного парсинга XML

Сообщение porcelanosa »

Хорошо, я и использую simpleXml. Затем в цикле пробегаю и сохраняю в БД через Pdo
10 строк кода... Но занимает это оооочень много времени
mcintosh-club.ru - первый мой сайт с использование Yii //
Акустика Sonus Faber Hi-End класса//
Необрезная доска и другие пиломатериалы
Аватара пользователя
rugabarbo
Сообщения: 1063
Зарегистрирован: 2015.06.21, 16:21
Контактная информация:

Re: Разбиение на части длинного парсинга XML

Сообщение rugabarbo »

Вы не вникаете в то, что я пишу.

Загрузка файла целиком в SimpleXML !== Чтение файла с помощью XMLReader с загрузкой отдельных узлов в SimpleXML
Аватара пользователя
porcelanosa
Сообщения: 570
Зарегистрирован: 2010.03.16, 04:31
Откуда: Москва

Re: Разбиение на части длинного парсинга XML

Сообщение porcelanosa »

Вот пример моего кода

Код: Выделить всё

$db = mysql_simple_connect($db_host, $db_name, $mysql_user, $mysql_pass);

$production = simplexml_load_file("original/production.xml");

/**
 * Сохраняем Группы
 * @param $top
 * @param $level
 * @param $db PDO
 */
function saveGroup($top, $level, $db) {
    $update =0; // счетчик обновлений
    $insert =0; // счетчик вставок
    $table_name = 'groups';
    foreach($top as $sub)
    {
        $id = $sub->id;
        $stmt = $db->query("SELECT * FROM $table_name WHERE hg_id = '$id'");
        echo $stmt->rowCount().'<br>'.$id.'<br>';
        if($stmt->rowCount() == 0) {
            $stmt = $db->prepare("INSERT INTO $table_name (id, parent_id, name ) VALUES (:id,:parent_id, :name)");
            $stmt->execute(array(
                'id' => $sub->id,
                'parent_id' => $sub->parent,
                'name' => $sub->name,
            ));
            $insert++;
        }
        else {
            $stmt = $db->prepare("UPDATE $table_name SET  parent_id = :parent_id, name = :name WHERE id = :id");
            $stmt->execute(array(
                'id' => $sub->id,
                'parent_id' => $sub->parent,
                'name' => $sub->Наименование,
            ));
            $update++;
        }

        if(count($sub->groups)>0) {
            saveGroup($sub->groups->children(), $level, $db);
        }
    }
    echo '<br>ОБновлено групп ' . $update;
    echo '<br>Добавлено групп ' . $insert;
}
И да, наверное, не самое страшное в парсинге XML
Там еще скачивание картинок есть

Т.е. задача разбить любой скрипт на этапы?
Выполнять по N операций за цикл?
Есть где-то примеры реализации?
mcintosh-club.ru - первый мой сайт с использование Yii //
Акустика Sonus Faber Hi-End класса//
Необрезная доска и другие пиломатериалы
Аватара пользователя
rugabarbo
Сообщения: 1063
Зарегистрирован: 2015.06.21, 16:21
Контактная информация:

Re: Разбиение на части длинного парсинга XML

Сообщение rugabarbo »

XMLReader работает как курсор. Например, вы можете двигать его с помощью функции XMLReader::next(). Таким образом, на каждом этапе чтения можно перемещать курсор к нужной точке, не загружая весь документ в память.

XMLReader гарантированно избавит вас от расходов памяти и позволит читать документы любого объёма маленькими частями. Что касается времени выполнения - всё будет зависеть от вашей реализации.

Пример последовательного чтения каждого отдельного узла документа скинул выше, вы его открывали?
Аватара пользователя
porcelanosa
Сообщения: 570
Зарегистрирован: 2010.03.16, 04:31
Откуда: Москва

Re: Разбиение на части длинного парсинга XML

Сообщение porcelanosa »

Спасибо, буду разбираться.
Направление задано - это главное.
mcintosh-club.ru - первый мой сайт с использование Yii //
Акустика Sonus Faber Hi-End класса//
Необрезная доска и другие пиломатериалы
Ответить