Замена функции Parsing с помощью XMLReader в конкретном PHP-коде

Я пытаюсь использовать PHP-скрипт для синтаксического анализа большого XML-файла (около 450 МБ) для базы данных MYSQL в определенную структуру и определения, включающие элементы XML. Проблема заключается в том, что исходный скрипт использует file_get_contents и SimpleXMLElement для его выполнения, но задание на кукурузу, выполняемое сервером, останавливается из-за объема XML-файла. Я не эксперт по PHP, поэтому я купил это программное обеспечение XMLSplit и разделил XML на 17 разделенных XML-файлов, каждый размером 30 МБ, проанализировал их один за другим, используя один и тот же скрипт. Тем не менее, в выходной базе данных не было большого количества входных данных, и у меня есть серьезные сомнения в том, будет ли такой же вывод исходного файла, если он не будет разделен автоматически и разобран один за другим.

Итак, я решил использовать XMLReader с этим точным скриптом PHP для синтаксического анализа этого большого XML-файла, но до сих пор мне не удалось просто заменить код синтаксического анализа и сохранить остальную функциональность.

Я включил сценарий ниже, я бы очень признателен, если кто-то поможет мне это сделать.

<?php set_time_limit(0); ini_set('memory_limit', '1024M'); include_once('../db.php'); include_once(DOC_ROOT.'/include/func.php'); mysql_query("TRUNCATE screenshots_list"); mysql_query("TRUNCATE pages"); mysql_query("TRUNCATE page_screenshots"); $xmlstr = file_get_contents('t_info.xml'); $xml = new SimpleXMLElement($xmlstr); foreach ($xml->template as $item) { //print_r($item); $sql = sprintf("REPLACE INTO templates SET id = %d, state = %d, price = %d, exc_price = %d, inserted_date = '%s', update_date = '%s', downloads = %d, type_id = %d, type_name = '%s', is_flash = %d, is_adult = %d, width = '%s', author_id = %d, author_nick = '%s', package_id = %d, is_full_site = %d, is_real_size = %d, keywords = '%s', sources = '%s', description = '%s', software_required = '%s'", $item->id, $item->state, $item->price, $item->exc_price, $item->inserted_date, $item->update_date, $item->downloads, $item->template_type->type_id, $item->template_type->type_name, $item->is_flash, $item->is_adult, $item->width, $item->author->author_id, $item->author->author_nick, $item->package->package_id, $item->is_full_site, $item->is_real_size, $item->keywords, $item->sources, $item->description, $item->software_required); //echo '<br>'.$sql; mysql_query($sql); //print_r($item->screenshots_list->screenshot); foreach ($item->screenshots_list->screenshot as $scr) { $main = (!empty($scr->main_preview)) ? 1 : 0; $small = (!empty($scr->small_preview)) ? 1 : 0; insert_data($item->id, 'screenshots_list', 0, $scr->uri, $scr->filemtime, $main, $small); } foreach ($item->styles->style as $st) { insert_data($item->id, 'styles', $st->style_id, $st->style_name); } foreach ($item->categories->category as $cat) { insert_data($item->id, 'categories', $cat->category_id, $cat->category_name); } foreach ($item->sources_available_list->source as $so) { insert_data($item->id, 'sources_available_list', $so->source_id, ''); } foreach ($item->software_required_list->software as $soft) { insert_data($item->id, 'software_required_list', $soft->software_id, ''); } //print_r($item->pages->page); if (!empty($item->pages->page)) { foreach ($item->pages->page as $p) { mysql_query(sprintf("REPLACE INTO pages SET tpl_id = %d, name = '%s', id = NULL ", $item->id, $p->name)); $page_id = mysql_insert_id(); if (!empty($p->screenshots->scr)) { foreach ($p->screenshots->scr as $psc) { $href = (!empty($psc->href)) ? (string)$psc->href : ''; mysql_query(sprintf("REPLACE INTO page_screenshots SET page_id = %d, description = '%s', uri = '%s', scr_type_id = %d, width = %d, height = %d, href = '%s'", $page_id, $psc->description, $psc->uri, $psc->scr_type_id, $psc->width, $psc->height, $href)); } } } }}?> 

Чтобы выделить строки кода, о которых идет речь, это та часть, в которой я пытаюсь заменить методом XMLReader, не затрагивая функциональность остальной части скрипта:

  $xmlstr = file_get_contents('t_info.xml'); $xml = new SimpleXMLElement($xmlstr); foreach ($xml->template as $item) { 

Я бы очень признателен за ваши решения …

Можно расширить позицию считывателя XML в DOMElement. Этот элемент не связан с DOMDocument, поэтому его нельзя напрямую преобразовать в SimpleXMLElement, но его можно импортировать в DOMDocument.

 $xml = <<<'XML' <templates> <template> <styles> <style>TEST</style> </styles> </template> </templates> XML; $reader = new XMLReader; $reader->open('data://text/xml;base64,'.base64_encode($xml)); $dom = new DOMDocument; // look for the first template element while ($reader->read() && $reader->localName !== 'template') { continue; } // while you have an template element while ($reader->localName === 'template') { // convert to SimpleXMLElement $element = simplexml_import_dom( // expand to a DOMElement in the prepared document object $reader->expand($dom) ); var_dump( $element ); // move to the next template sibling $reader->next('template'); } 

Вывод:

 object(SimpleXMLElement)#3 (1) { ["styles"]=> object(SimpleXMLElement)#4 (1) { ["style"]=> string(4) "TEST" } } 

Я обычно использую DOM + Xpath и не конвертирую его в SimpleXML, но этот подход должен хорошо работать для вашей проблемы.