Created
December 7, 2012 13:20
-
-
Save vasia123/4233238 to your computer and use it in GitHub Desktop.
Разбор большого XML файла с помощью PHP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// convert http://webi.ru/webi_articles/big_xml.html to class | |
class webi_xml | |
{ | |
var $webi_depth; // счетчик, для отслеживания глубины вложенности | |
var $this->webi_tag_open; // будет содержать массив открытых в данный момент тегов | |
var $this->webi_data_temp; // этот массив будет содержать данные одного тега | |
private function __construct() | |
{ | |
$this->webi_depth = 0; | |
$this->webi_tag_open= array(); | |
} | |
#################################################### | |
### функция работы с данными | |
function data ($parser, $data) | |
{ | |
// добавляем данные в массив с указанием вложенности и открытого в данный момент тега | |
$this->webi_data_temp[$this->webi_depth][$this->webi_tag_open[$this->webi_depth]]['data'].=$data; | |
} | |
############################################ | |
#################################################### | |
### функция открывающих тегов | |
function startElement($parser, $name, $attrs) | |
{ | |
// если уровень вложенности уже не нулевой, значит один тег уже открыт | |
// и данные из него уже в массиве, можно их обработать | |
if ($this->webi_depth) | |
{ | |
// здесь начинается обработка данных, например добаление в базу, сохранение в файл и т.д. | |
// $this->webi_tag_open содержит цепочку открытых тегов по уровню вложенности | |
// например $this->webi_tag_open[$this->webi_depth] содержит название открытого тега чья информация сейчас обрабатывается | |
// $this->webi_depth уровень вложенности тега | |
// $this->webi_data_temp[$this->webi_depth][$this->webi_tag_open[$this->webi_depth]]['attrs'] массив атрибутов тега | |
// $this->webi_data_temp[$this->webi_depth][$this->webi_tag_open[$this->webi_depth]]['data'] данные тега | |
print 'данные '.$this->webi_tag_open[$this->webi_depth].'--'.($this->webi_data_temp[$this->webi_depth][$this->webi_tag_open[$this->webi_depth]]['data']).'<br>'; | |
print_r($this->webi_data_temp[$this->webi_depth][$this->webi_tag_open[$this->webi_depth]]['attrs']); | |
print '<br>'; | |
print_r($this->webi_tag_open); // массив открытых тегов | |
print '<hr>'; | |
// после обработки данных удаляем их для освобождения памяти | |
unset($this->webi_data_temp[$this->webi_depth]); | |
} | |
// теперь пошло открытие следующего тега и дальше обработка его произойдет на следующем шаге | |
$this->webi_depth++; // увеличиваем вложенность | |
$this->webi_tag_open[$this->webi_depth]=$name; // добавляем открытый тег в массив информаци | |
$this->webi_data_temp[$this->webi_depth][$name]['attrs']=$attrs; // теперь добавляем атрибуты тега | |
} | |
############################################### | |
################################################# | |
## функция закрывающих тегов | |
function endElement($parser, $name) | |
{ | |
// здесь начинается обработка данных, например добаление в базу, сохранение в файл и т.д. | |
// $this->webi_tag_open содержит цепочку открытых тегов по уровню вложенности | |
// например $this->webi_tag_open[$this->webi_depth] содержит название открытого тега чья информация сейчас обрабатывается | |
// $this->webi_depth уровень вложенности тега | |
// $this->webi_data_temp[$this->webi_depth][$this->webi_tag_open[$this->webi_depth]]['attrs'] массив атрибутов тега | |
// $this->webi_data_temp[$this->webi_depth][$this->webi_tag_open[$this->webi_depth]]['data'] данные тега | |
print 'данные '.$this->webi_tag_open[$this->webi_depth].'--'.($this->webi_data_temp[$this->webi_depth][$this->webi_tag_open[$this->webi_depth]]['data']).'<br>'; | |
print_r($this->webi_data_temp[$this->webi_depth][$this->webi_tag_open[$this->webi_depth]]['attrs']); | |
print '<br>'; | |
print_r($this->webi_tag_open); | |
print '<hr>'; | |
unset($this->webi_data_temp); // после обработки данных удаляем массив с данными целиком, так как произошло закрытие тега | |
unset($this->webi_tag_open[$this->webi_depth]); // удаляем информацию об этом открытом теге... так как он закрылся | |
$this->webi_depth--; // уменьшаем вложенность | |
} | |
############################################ | |
function start($file) { | |
$xml_parser = xml_parser_create(); | |
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true); | |
// указываем какие функции будут работать при открытии и закрытии тегов | |
xml_set_element_handler($xml_parser, Array(&$this, "startElement"), Array(&$this, "endElement")); | |
// указываем функцию для работы с данными | |
xml_set_character_data_handler($xml_parser, Array(&$this, 'data')); | |
// открываем файл | |
$fp = fopen($file, "r"); | |
$perviy_vxod=1; // флаг для проверки первого входа в файл | |
$data=""; // сюда собираем частями данные из файла и отправляем в разборщик xml | |
// цикл пока не найден конец файла | |
while (!feof ($fp) and $fp) | |
{ | |
$simvol = fgetc($fp); // читаем один символ из файла | |
$data.=$simvol; // добавляем этот символ к данным для отправки | |
// если символ не завершающий тег, то вернемся к началу цикла и добавим еще один символ к данным, и так до тех пор, пока не будет найден закрывающий тег | |
if($simvol!='>') { continue;} | |
// если закрывающий тег был найден, теперь отправим эти собранные данные в обработку | |
// проверяем, если это первый вход в файл, то удалим все, что находится до тега <? | |
// так как иногда может встретиться мусор до начала XML (корявые редакторы, либо файл получен скриптом с другого сервера) | |
if($perviy_vxod) {$data=strstr($data, '<?'); $perviy_vxod=0;} | |
// теперь кидаем данные в разборщик xml | |
if (!xml_parse($xml_parser, $data, feof($fp))) { | |
// здесь можно обработать и получить ошибки на валидность... | |
// как только встретится ошибка, разбор прекращается | |
echo "<br>XML Error: ".xml_error_string(xml_get_error_code($xml_parser)); | |
echo " at line ".xml_get_current_line_number($xml_parser); | |
break; | |
} | |
// после разбора скидываем собранные данные для следующего шага цикла. | |
$data=""; | |
} | |
fclose($fp); | |
xml_parser_free($xml_parser); | |
} | |
} | |
$newClass = new webi_xml(); // Создаем экземпляр класса | |
$newClass->start($file); // Запускаем файл |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment