Парсинг XML и JSON на PHP

апрель 22 , 2015
Метки:

В этой заметке приведены инструкции, как распарсить xml-строку, преобразовать ее в json-объект или ассоциативный массив и получить нужные данные

Задача: есть xml-строка. Нужно распарсить эту строку и вытащить из нее все данные. Пример xml-строки списка товаров

    
        
            
                1234
                Телефон Nokia
                100 у.е.
                
                    Пластик
                    Белый
                
                
                    
                        1024
                        http://mysite.com/images/photo1.jpg
                    
                    
                        2096
                        http://mysite.com/images/photo2.png
                    
                
            
            
                24789
                Планшет LG
                250 у.е.
                
                    Металл
                    Китай
                    LG
                
                
                    
                        548
                        http://mysite.com/images/photo10.jpg
                    
                
            
        
    

Преобразуем xml-строку в json-строку

    $xml = simplexml_load_string($xml_string);
    $json_string = json_encode($xml);

Дальше у нас 2 варианта, можно преобразовать строку в объект json, а можно в ассоциативный массив. Преобразование выполняет функция json_decode($json_string[, true]). По умолчанию получим объект, но если второй параметр установить в true, то строка преобразуется в ассоциативный массив. На мой взгляд, работать с json-объектом удобнее, но это дело вкуса. Рассмотрим оба варианта

Работаем с объектом

    $json = json_decode($json_string);
    $goods = $json->goods->good;
    foreach($goods as $good) {
        echo 'good_id: '.$good->good_id.'
'; echo 'name: '.$good->name.'
'; echo 'price: '.$good->price.'
'; echo 'params:
'; if (isset($good->params->material)) echo '___material: '.$good->params->material.'
'; if (isset($good->params->color)) echo '___color: '.$good->params->color.'
'; if (isset($good->params->country)) echo '___country: '.$good->params->country.'
'; if (isset($good->params->vendor)) echo '___vendor: '.$good->params->vendor.'
'; echo 'photos:
'; $photos = $good->photos->photo; if(!is_array($photos)) // Если это не массив $photos = array(0 => $photos); foreach($photos as $key => $photo) { echo '___photo number '.strval($key+1).'
'; echo '______size: '.$photo->size.'
'; echo '______url: '.$photo->url.'
'; } echo '
'; }

Для проверки наличия в узле params нужных свойств используем функцию isset(). Обратите внимание на работу с фото. $good->photos->photo получит разный результат для первого и второго товара. В первом товаре у нас 2 узла photo, и мы получим их массив. Во втором случае узел один, и при этом возвращается объект. Чтобы нам не приходилось вводить условия, как получать информацию, перебором массива или прямым доступом к полям объекта, мы проверяем, является ли полученная переменная массивом, и если нет, "загоняем" ее в массив искусственно. В итоге мы всегда получаем массив с одним или несколькими объектами, которые обрабатываем обычным перебором.

Работаем с массивом

    $ar = json_decode($json_string, true);
    $goods = $ar['goods']['good'];
    foreach($goods as $good) {
        echo 'good_id: '.$good['good_id'].'
'; echo 'name: '.$good['name'].'
'; echo 'price: '.$good['price'].'
'; echo 'params:
'; if (isset($good['params']['material'])) echo '___material: '.$good['params']['material'].'
'; if (isset($good['params']['color'])) echo '___color: '.$good['params']['color'].'
'; if (isset($good['params']['country'])) echo '___country: '.$good['params']['country'].'
'; if (isset($good['params']['vendor'])) echo '___vendor: '.$good['params']['vendor'].'
'; echo 'photos:
'; $photos = $good['photos']['photo']; $keys = array_keys($photos); if (array_keys($keys) !== $keys) // Если массив ассоциативный $photos = array(0 => $photos); foreach($photos as $key => $photo) { echo '___photo number '.strval($key+1).'
'; echo '______size: '.$photo['size'].'
'; echo '______url: '.$photo['url'].'
'; } echo '
'; }

Принцип работы точно такой же, только обращаемся мы не к полям объекта, а к значениям массива. Проверка узла photos проходит немного иначе. Код $photos = $good['photos']['photo'] получит в любом случае массив, только нужно определить, является ли он ассоциативным. Соответствующая проверка подсмотрена во фреймворке Kohana

Метки:
Заходите в группу в контакте - https://vk.com/webdevkin
Анонсы статей, обсуждения интернет-магазинов, vue, фронтенда, php, гита.
Истории из жизни айти и обсуждение кода.
Как Вам статья? Оцените!