По идее столько всего понаписано, чего огород то городить? От случая к случаю, конечно, пользуюсь библиотеками PHP. Но вместе с этим, есть объективные причины ими пользоваться не всегда. Далее покажу совсем крохотный класс-конвертер XML в массив на базе xml_parser.
После парсинга данным классом получаем древовидный массив.
Вот пример HTML кода, который мы будет парсить:
1 2 3 4 5 6 7 8 9 10 11 |
<html> <head> </head> <body id="main"> <a href="//shra.ru"></a> <p class="sigma">Hello</p> aaa <p>Second line</p> <a href="http://farmugroza.ru"></a> </body> </html> |
В нем есть несколько разных тегов, а также инлайн строка — «ааа».
Парсим с помощью SimpleXML
1 |
simplexml_load_string($string); |
Получаем SimpleXMLElement объект вида:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
SimpleXMLElement Object ( [head] => SimpleXMLElement Object ( [0] => ) [body] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => main ) [a] => Array ( [0] => SimpleXMLElement Object ( [@attributes] => Array ( [href] => http://shra.ru ) ) [1] => SimpleXMLElement Object ( [@attributes] => Array ( [href] => http://farmugroza.ru ) ) ) [p] => Array ( [0] => Hello [1] => Second line ) ) ) |
Т.е на выходе какая то мешанина из объектов и массивов, теги группируются в массивы, инлайн данные вообще потеряны.
Теперь тоже самое парсим моей самоделкой.
1 |
myXMLparser::parse($string); |
Результат вот такой:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
Array ( [0] => Array ( [tag] => HTML [value] => [0] => Array ( [tag] => HEAD [value] => ) [1] => Array ( [tag] => BODY [value] => [0] => Array ( [tag] => A [value] => [HREF] => http://shra.ru ) [1] => Array ( [tag] => P [value] => Hello [CLASS] => sigma ) [2] => Array ( [value] => aaa ) [3] => Array ( [tag] => P [value] => Second line ) [4] => Array ( [tag] => A [value] => [HREF] => http://farmugroza.ru ) ) [ID] => main ) ) |
Т.е. получаем иерархический массив тегов, атрибуты перечисляются как хеш-массив, теги — как нумерованный массив. Я также делал вариант, когда дочерние элементы группировались в xeш — childs (переделать не сложно).
Класс для преобразования XML в массив
А теперь, код класса — в студию :)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
class myXMLparser { //XML парсер static function parse($xmlstring) { $xml = xml_parser_create(); xml_parse_into_struct($xml, $xmlstring, $parsedSim); xml_parser_free($xml); unset($dataxml); print_r($parsedSim); $parsedSim = myXMLparser::convertXarToPar($parsedSim); return $parsedSim; } /* функция преобразования */ static private function convertXarToPar(&$parsed) { $data = array(); $cursor = 0; myXMLparser::convertExplore($data, $parsed, $cursor); return $data; } /* рекурсивная часть преобразователя */ static private function convertExplore(&$data, &$parsed, &$cursor) { while (isset($parsed[$cursor])) { $v = &$parsed[$cursor ++]; //type value analysis switch($v['type']) { case 'open': $tag = $v['tag']; $j = &$data[]; $j['tag'] = $tag; $j['value'] = isset($v['value']) ? $v['value'] : ''; if (isset($v['attributes'])) $data += $v['attributes']; myXMLparser::convertExplore($j, $parsed, $cursor); break; case 'close': return; case 'cdata': if (empty($v['value']) || trim($v['value']) == '') break; else { $j = &$data[]; $j['value'] = trim($v['value']); } break; case 'complete': $tag = $v['tag']; $j = &$data[]; $j['tag'] = $tag; $j['value'] = isset($v['value']) ? $v['value'] : ''; if (isset($v['attributes'])) $j += $v['attributes']; break; } } } } |
Использование myXMLparser
В классе используется только одна public функция и та является static. Обернул в класс только для того, чтобы не засорять пространство имен и обернуть 3 функции. Используется так:
1 |
$resultArray = myXMLparser::parse($your_xml_string); |
Попробуй
$xml = simplexml_load_string(‘xml-код’);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
echo «
»;
Люблю я, видишь ли, велосипеды изобретать. :)
Хороший скрипт, только ошибка в нем, в 32 сроке, блин столько времени на это потратил.
Вместо
if (isset($v[‘attributes’])) $data += $v[‘attributes’];
Нужно делать или:
if (isset($v[‘attributes’])) $j[‘attributes’] = $v[‘attributes’];
Или:
if (isset($v[‘attributes’])) $j += $v[‘attributes’];
Иначе часть информации теряется!!!