Как конвертировать XML в ассоциативный массив

Как конвертировать XML в ассоциативный массив

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

Решений этой проблемы, найденных в гугле было достаточно. Я нашел несколько разных способов, несколько библиотек, которые решали мои задачи. Но, как я уже написал выше, мне хотелось что-то простое, эффективное, и без использования сторонних библиотек. И, как мне кажется, я нашел оптимальный вариант конвертации XML в ассоциативный массив. И, для работы этого способа, достаточно будет всего одной PHP функции (для чтения файла) - file_get_contents().

В этой статье вы узнаете, как конвертировать XML в массив на PHP.

Шаг 1: Исходный XML-файл

Хотелось сделать дефолтный пример, с дефолтным файлом, как делают в дефолтных статьях. Но сегодня я решил добавить в эту статью реальный пример из проекта.

Поставим перед собой задачу: нужно парсить курсы валют из API, которые отдаются в XML. Погуглив, я нашел API finance.ua, которое решает нашу задачу, и отдаёт такой XML-файл. И на его примере мы и будем рассматривать текущую тему. source

Шаг 2: конвертируем содержимое XML-файла в строку

Для этого, как ранее и было написано, используется функция file_get_contents(). Присвоим содержимое файла переменной, для удобной работы с данными:

$url = 'http://resources.finance.ua/ru/public/currency-cash.xml';
$xml = file_get_contents($url);

Шаг 3: конвертация XML строки в объект

Теперь, стандартными средствами PHP, можно XML-строку преобразовать в объект, в котором к тегам можно обращаться по цепочке свойств объекта, например:

$xml_data->organizations->organization[0]->title['value']; // название первой организации из списка, т.е. Universal Bank 

Для этого воспользуемся функцией simplexml_load_string(), которой нужно передать XML строку:

$xml_data = simplexml_load_string($xml); // XML объект

И, обычно, в таком виде уже работают с XML-объектом, вызывая нужные методы/цепочки свойств. Но, в таком виде, работа с XML не всегда очевидна, особенно для новичков, потому, многие стремятся к тому, чтобы конвертировать XML в массив, так как это более привычный и удобный вариант работы с данными. И, к сожалению, в объекте $xml_data не существует магического метода ->toArray(), который конвертировал бы всю цепочку элементов в ассоциативный массив. Но, мы знаем, как сделать это самим.

Шаг 4: Конвертация XML-объекта в ассоциативный массив

Теперь текущий объект $xml_data нужно преобразовать в JSON с помощью функции json_encode().

$json = json_encode($xml_data); // json строка

После чего, нужно выполнить обратные действия, т.е. декодировать JSON в массив, используя функция json_decode():

$json_data = json_decode($json, true); // ассоциативный массив

Здесь может показаться немного нелогичным то, что сначала вызывается функция json_encode, а после чего, сразу json_decode. Но учитывая механику работы этих функций, всё сразу же становится на свои места.
json_encode - вырезает все лишние свойства, и конвертирует объект в JSON строку, оставляя только полезные данные
json_decode - преобразует JSON строку в массив

И, учитывая, что все ненужные данные были вырезаны, то ассоциатиыный массив, не содержит ничего лишнего: associative

Чего уже вполне достаточно для использования на практике, оперируя массивом.

Теперь в массиве все атрибуты элементов доступны под ключом @attributes, а элементы под ключом имени:

$organization = $json_data['organizations']['organization'][0]; // первая организация
$title = $organization['title']['@attributes']['value']; // title организации
$currencies = $organization = $organization['currencies']['c']; // курсы валют организации

Резюме

Вот так, оказывается просто можно преобразовать XML в ассоциативный массив. Нам для этого понадобилось не больше, чем 4 строки:

$xml = file_get_contents('http://resources.finance.ua/ru/public/currency-cash.xml');
$xml_data = simplexml_load_string($xml);
$json = json_encode($xml_data);
$json_data = json_decode($json, true);

И, помимо того, что вы теперь знаете, как происходит преобразование XML в массив, вы так же знаете, откуда спарсить курсы валют ^^.