SimpleXML. Начало работы
24.04.2013
Теги: PHP • Web-разработка • XML
Расширение SimpleXML предоставляет очень простой и легкий в использовании набор инструментов для преобразования XML в объект, с которым можно затем работать через его свойства и с помощью итераторов. SimpleXML присутствует в PHP начиная с версии 5.
Для наглядности, в качестве примера будем использовать XML, описывающий простой кулинарный рецепт, взятый с википедии.
<?xml version="1.0" encoding="UTF-8"?> <recipe name="хлеб" preptime="5" cooktime="180"> <title>Простой хлеб</title> <ingredient amount="3" unit="стакан">Мука</ingredient> <ingredient amount="0.25" unit="грамм">Дрожжи</ingredient> <ingredient amount="1.5" unit="стакан">Тёплая вода</ingredient> <ingredient amount="1" unit="чайная ложка">Соль</ingredient> <instructions> <step>Смешать все ингредиенты и тщательно замесить.</step> <step>Закрыть тканью и оставить на один час в тёплом помещении.</step> <step>Замесить ещё раз, положить на противень и поставить в духовку.</step> </instructions> </recipe>
Загрузка XML
Прежде чем начать обрабатывать данные, их нужно сначала загрузить. Для этого достаточно использовать функцию simplexml_load_file(). Она принимает имя файла, и возвращает объект типа SimpleXMLElement. И с этим объектом уже можно будет работать.
$xml = simplexml_load_file('recipe.xml'); print_r($xml);
SimpleXMLElement Object
(
[@attributes] => Array
(
[name] => хлеб
[preptime] => 5
[cooktime] => 180
)
[title] => Простой хлеб
[ingredient] => Array
(
[0] => Мука
[1] => Дрожжи
[2] => Тёплая вода
[3] => Соль
)
[instructions] => SimpleXMLElement Object
(
[step] => Array
(
[0] => Смешать все ингредиенты и тщательно замесить.
[1] => Закрыть тканью и оставить на один час в тёплом помещении.
[2] => Замесить ещё раз, положить на противень и поставить в духовку.
)
)
)
Кроме того, существует еще и функция simplexml_load_string(), которая берет XML не из файла, а из строки.
$str = file_get_contents('recipe.xml'); $xml = simplexml_load_string($str);
Получение данных
SimpleXML предоставляет очень удобный способ получения данных из XML. К примеру, для того чтобы получить какой-либо узел документа достаточно просто обратится к этому узлу по имени:
// Выводит содержимое элемента <title> echo $xml->title;
Поскольку ингредиентов у нас несколько, то $xml->ingredient будет массивом из четырех элементов. Перебрать все ингредиенты можно так:
foreach ( $xml->ingredient as $ingredient ) { echo $ingredient . '<br/>'; }
Для того что бы получить, к примеру, третий ингредиент (теплая вода), достаточно обратиться к нему по индексу:
$xml->ingredient[2]; // элементы массивы нумеруются с нуля
Шаги приготовления (step) являются дочерними для элемента instructions, чтобы получить их, нужно сначала получить instructions:
echo $xml->instructions->step; // выводит текст первого шага
Атрибуты
Работать с атрибутами тоже очень легко. Они доступны как ассоциативный массив своего элемента. То есть, для того что бы получить название рецепта (атрибут name корневого узла recipe), достаточно написать:
echo $xml['name'];
Или, для получения количества первого ингредиента можно написать так:
echo $xml->ingredient['amount'];
Сейчас мы рассмотрели только один способ получения данных: когда нам уже известны названия узлов и атрибутов. Но случается и так, когда структура XML файла заранее не известна, но нам нужно его обработать. SimpleXML предоставляет и такую возможность.
Получение дочерних узлов
Метод children() возвращает список дочерних элементов. В нашем случае $xml — корневая ветвь, и если написать:
$nodes = $xml->children(); echo $nodes[0];
то получим содержимое элемента <title>, а если:
$nodes = $xml->children(); echo $nodes[2];
то второй ингредиент.
Обойти все дочерние ветви первого уровня легко можно при помощи цикла foreach:
echo '<ul>'; foreach ( $xml->children() as $node ) { if ( count($node) == 0 ) echo '<li>' . $node . '</li>'; } echo '</ul>';
Результат:
<ul> <li>Простой хлеб</li> <li>Мука</li> <li>Дрожжи</li> <li>Тёплая вода</li> <li>Соль</li> </ul>
Фукция count() позволяет определить количество дочерних узлов.
Для того, чтобы получить имя текущий ветви, используется метод getName():
$nodes = $xml->children(); echo $nodes[0]->getName(); // выведет title
Получение атрибутов
Получить список атрибутов для текущего элемента поможет метод attributes(). По функционалу и механизму работы он аналогичен методу children(), за тем исключением, что здесь идет работа с атрибутами.
$nodes = $xml->children(); // все атрибуты узла <ingredient>Мука</ingredient> foreach ( $nodes[1]->attributes() as $name => $value ) { echo 'атрибут ' . $name . ', значение ' . $value . '<br/>'; }
Результат:
атрибут amount, значение 3<br/> атрибут unit, значение стакан<br/>
Изменение значений узлов и атрибутов
Объект SimpleXMLElement позволяет манипулировать всеми элементами:
$xml = simplexml_load_file('recipe.xml'); $xml->title = 'Ржаной хлеб'; $xml->ingredient[0] = 'Ржаная мука'; print_r($xml); $xml->ingredient[2]['amount'] = '300'; $xml->ingredient[2]['unit'] = 'грамм'; print_r($xml->ingredient[2]);
Результат:
SimpleXMLElement Object
(
[@attributes] => Array
(
[name] => хлеб
[preptime] => 5
[cooktime] => 180
)
[title] => Ржаной хлеб
[ingredient] => Array
(
[0] => Ржаная мука
[1] => Дрожжи
[2] => Тёплая вода
[3] => Соль
)
[instructions] => SimpleXMLElement Object
(
[step] => Array
(
[0] => Смешать все ингредиенты и тщательно замесить.
[1] => Закрыть тканью и оставить на один час в тёплом помещении.
[2] => Замесить ещё раз, положить на противень и поставить в духовку.
)
)
)
SimpleXMLElement Object
(
[@attributes] => Array
(
[amount] => 300
[unit] => грамм
)
[0] => Тёплая вода
)
Добавление элементов и атрибутов
Чтобы добавить дочерний элемент к текущему, достаточно использовать метод addChild(). Первым параметром идет имя нового элемента, вторым значение, которое задавать необязательно.
Добавим еще один шаг к инструкциям:
$node = $xml->instructions; // получаем ветвь инструкций $node->addChild('step', 'Почитать газету'); // добавляем элемент print_r($node);
Результат:
SimpleXMLElement Object
(
[step] => Array
(
[0] => Смешать все ингредиенты и тщательно замесить.
[1] => Закрыть тканью и оставить на один час в тёплом помещении.
[2] => Замесить ещё раз, положить на противень и поставить в духовку.
[3] => Почитать газету
)
)
Метод addAttribute() позволяет добавить атрибут к текущему узлу. Первый параметр это имя атрибута, второй значение.
$node = $xml->instructions; // получаем ветвь инструкций $step = $node->addChild('step', 'Почитать газету'); // добавляем элемент $step->addAttribute('newspaper', 'Аргументы и факты'); // добавляем артибут print_r($step);
Результат:
SimpleXMLElement Object
(
[@attributes] => Array
(
[newspaper] => Аргументы и факты
)
[0] => Почитать газету
)
Использование XPath
SimpleXML включает в себя встроенную поддержку XPath. Поиск всех элементов <step>:
foreach ($xml->xpath('//step') as $step) { echo $step . '<br/>'; }
Результат:
Смешать все ингредиенты и тщательно замесить.<br/> Закрыть тканью и оставить на один час в тёплом помещении.<br/> Замесить ещё раз, положить на противень и поставить в духовку.<br/>
Взаимодействие с DOM
PHP может преобразовывать XML узлы из SimpleXML в формат DOM и наоборот. Этот пример показывает, как можно изменить DOM элемент в SimpleXML:
$dom = new DOMDocument('1.0', 'utf-8'); $dom->load('recipe.xml'); $xml = simplexml_import_dom($dom);
Дополнительная информация
- Работа с XML средствами PHP
- Блог на Laravel 7, часть 17. Временная зона для пользователей, деплой на хостинг TimeWeb
- Блог на Laravel 7, часть 16. Роль нового пользователя, сообщение админу о новом посте
- Блог на Laravel 7, часть 15. Восстановление постов, slug для категории, поста и страницы
- Блог на Laravel 7, часть 14. Валидация данных и права доступа при загрузке изображений
- Блог на Laravel 7, часть 13. Загрузка и ресайз изображений для категорий и постов блога
- Блог на Laravel 7, часть 12. Доп.страницы сайта в панели управления и в публичной части
Поиск: PHP • Web-разработка • XML