Created
September 22, 2016 17:21
-
-
Save ikenfin/27ff6a7f9710b587dc32d5b21d8a3a4e to your computer and use it in GitHub Desktop.
Файлы к статье о XMLReader (http://ikfi.ru/article/parsim-xml-s-pomoschju-xmlreader)
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 | |
/* | |
Родительский класс для XML импортеров. | |
*/ | |
class AbstractAdvertisementXMLReader { | |
protected $reader; | |
protected $result = array(); | |
// события | |
protected $_eventStack = array(); | |
/* | |
Конструктор класса. | |
Создает сущность XMLReader и загружает xml, либо бросает исключение | |
*/ | |
public function __construct($xml_path) { | |
$this->reader = new XMLReader(); | |
if(is_file($xml_path)) | |
$this->reader->open($xml_path); | |
else throw new Exception('XML file {'.$xml_path.'} not exists!'); | |
} | |
/* | |
Потоково парсит xml и вызывает методы для определенных элементов | |
напр. | |
при обнаружении элемента <Rubric> попытается вызвать метод parseRubric | |
все методы парсинга должны быть public или protected. | |
*/ | |
public function parse() { | |
$this->reader->read(); | |
while($this->reader->read()) { | |
if($this->reader->nodeType == XMLREADER::ELEMENT) { | |
$fnName = 'parse' . $this->reader->localName; | |
if(method_exists($this, $fnName)) { | |
$lcn = $this->reader->name; | |
// стреляем по началу парсинга блока | |
$this->fireEvent('beforeParseContainer', array('name' => $lcn)); | |
// пробежка по детям | |
if($this->reader->name == $lcn && $this->reader->nodeType != XMLREADER::END_ELEMENT) { | |
// стреляем событие до парсинга элемента | |
$this->fireEvent('beforeParseElement', array('name' => $lcn)); | |
// вызываем функцию парсинга | |
$this->{$fnName}(); | |
// стреляем событием по названию элемента | |
$this->fireEvent($fnName); | |
// стреляем событием по окончанию парсинга элемента | |
$this->fireEvent('afterParseElement', array('name' => $lcn)); | |
} | |
elseif($this->reader->nodeType == XMLREADER::END_ELEMENT) { | |
// стреляем по окончанию парсинга блока | |
$this->fireEvent('afterParseContainer', array('name' => $lcn)); | |
} | |
} | |
} | |
} | |
} | |
/* | |
Вызывается при каждом распознавании | |
*/ | |
public function onEvent($event, $callback) { | |
if(!isset($this->_eventStack[$event])) //!is_array($this->_eventStack[$event])) | |
$this->_eventStack[$event] = array(); | |
$this->_eventStack[$event][] = $callback; | |
return $this; | |
} | |
/* | |
Выстреливает событие | |
*/ | |
public function fireEvent($event, $params = null, $once = false) { | |
if($params == null) $params = array(); | |
$params['context'] = $this; | |
if(!isset($this->_eventStack[$event])) | |
return false; | |
$count = count($this->_eventStack[$event]); | |
if(isset($this->_eventStack[$event]) && $count > 0) { | |
for($i = 0; $i < $count; $i++) { | |
call_user_func_array($this->_eventStack[$event][$i], $params); | |
if($once == true) { | |
array_splice($this->_eventStack[$event], $i, 1); | |
} | |
} | |
} | |
} | |
/* | |
Получить результаты парсинга | |
*/ | |
public function getResult() { | |
return $this->result; | |
} | |
/* | |
Очистить результаты парсинга | |
*/ | |
public function clearResult() { | |
$this->result = array(); | |
} | |
} |
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 | |
class ConfigXMLReader extends AbstractAdvertisementXMLReader{ | |
/* | |
Парсит наценки | |
*/ | |
protected function parseRatio() { | |
if($this->reader->nodeType == XMLREADER::ELEMENT && $this->reader->localName == 'Ratio') { | |
$ratio = array( | |
'group_id' => $this->reader->getAttribute('group_id'), | |
'id' => $this->reader->getAttribute('id'), | |
'value' => $this->reader->getAttribute('value') | |
); | |
$this->reader->read(); | |
if($this->reader->nodeType == XMLREADER::TEXT) | |
$ratio['name'] = $this->reader->value; | |
$this->result['ratios'][] = $ratio; | |
} | |
} | |
/* | |
Парсит настройки несовместимых наценок | |
*/ | |
protected function parseRatioException() { | |
if($this->reader->nodeType == XMLREADER::ELEMENT && $this->reader->localName == 'RatioException') { | |
$ratioException = array( | |
'id_1' => $this->reader->getAttribute('id_1'), | |
'id_2' => $this->reader->getAttribute('id_2') | |
); | |
$this->result['ratioExceptions'][] = $ratioException; | |
} | |
} | |
} |
Я что-то не уловил, или условие AbstractAdvertisementXMLReader.php:64 никогда не выполнится, т.к. противоречит AbstractAdvertisementXMLReader.php:41 ?
Я что-то не уловил, или условие AbstractAdvertisementXMLReader.php:64 никогда не выполнится, т.к. противоречит AbstractAdvertisementXMLReader.php:41 ?
Да, видимо 5 лет назад, когда писал этот код знатно косякнул с after/before container событиями (если честно, то я даже не помню зачем вообще их делал, поскольку так и не использовал ни разу).
Думаю самым простым решением будет просто выпилить :50 и с :64 .. :67.
А вообще, надо будет собраться и переписать и статью и примеры.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Привет, а не подскажите как с помощью данного класса можно парсить вложенные элементы?
А хотя уже методами parse добился нужного результата, спасибо.