simplexml_import_dom()
SimpleXML — расширение PHP для работы с XML. Функция simplexml_import_dom() преобразует узел DOM в объект SimpleXMLElement.
Введение
PHP предоставляет два различных способа работы с XML: расширение DOM, которое мощное и соответствует стандартам, но многословно, и SimpleXML, который жертвует частью этой мощи ради гораздо более удобного API в стиле свойств объекта. simplexml_import_dom() — это мост между ними: функция принимает узел из DOM-дерева и возвращает SimpleXMLElement, оборачивающий те же данные.
Это полезно, когда вы выполнили трудоёмкую работу с DOM (валидацию по схеме, использование XPath, манипуляции с пространствами имён), но хотите читать результат с помощью лаконичного синтаксиса SimpleXML. На этой странице объясняется, как работает функция, когда к ней стоит обращаться, и какие подводные камни встречаются чаще всего.
Синтаксис
simplexml_import_dom(
object $node,
?string $class_name = SimpleXMLElement::class
): SimpleXMLElement|null$node— DOM-узел для импорта. На практике это экземплярDOMNode,DOMElementилиDOMDocument. Если передатьDOMDocument, импортируется его корневой элемент (document element).$class_name— необязательный класс, расширяющийSimpleXMLElement. Возвращаемый объект будет экземпляром этого класса, что позволяет добавлять собственные вспомогательные методы.
Функция возвращает SimpleXMLElement в случае успеха или null, если узел не удалось импортировать. Функция доступна начиная с PHP 5.1.3.
Импорт целого документа
Наиболее распространённый случай — разбор или построение документа с помощью DOM с последующей передачей корня в SimpleXML для удобного чтения:
<?php
$dom = new DOMDocument();
$dom->loadXML('<?xml version="1.0"?>
<book>
<title>PHP Basics</title>
<author>Jane Doe</author>
</book>');
$book = simplexml_import_dom($dom);
// Read with SimpleXML's property syntax instead of DOM method calls:
echo $book->title; // PHP Basics
echo "\n";
echo $book->author; // Jane Doe
?>Передача объекта $dom (DOMDocument) импортирует его корневой элемент, поэтому $book соответствует <book>. Сравните это с эквивалентом на DOM — $dom->getElementsByTagName('title')->item(0)->nodeValue — и привлекательность SimpleXML станет очевидной.
Импорт отдельного созданного элемента
Вы также можете программно создать узел с помощью DOM и импортировать только этот узел:
Здесь мы создаём элемент <title>, прикрепляем его к документу и передаём корневой элемент документа ($dom->documentElement) в simplexml_import_dom(). Метод asXML() затем сериализует SimpleXMLElement обратно в строку.
Связь с остальным API SimpleXML
simplexml_import_dom() — это обратная функция по отношению к dom_import_simplexml(), которая преобразует SimpleXMLElement обратно в DOMElement. Вместе они позволяют свободно переходить между двумя расширениями:
| Что есть | Что нужно | Используйте |
|---|---|---|
| DOM-узел | SimpleXMLElement | simplexml_import_dom() |
SimpleXMLElement | DOMElement | dom_import_simplexml() |
Если вы начинаете со строки или файла, а не с DOM-дерева, DOM обычно не нужен — используйте simplexml_load_string() или simplexml_load_file() напрямую.
Подводные камни
- Общие данные. Возвращаемый
SimpleXMLElementявляется представлением тех же данных, на которые ссылается DOM-узел, а не независимой копией. Сохраняйте исходный DOM-объект в области видимости — если он будет уничтожен сборщиком мусора, обёртка SimpleXML может стать неработоспособной. - Недопустимый ввод возвращает
null. Возвратnull(или, в PHP 8+,TypeError, если аргумент вообще не является DOM-объектом) сигнализирует об ошибке — всегда проверяйте результат перед цепочкой вызовов методов. - Пользовательский класс должен расширять
SimpleXMLElement. Передача имени не связанного класса для$class_nameявляется ошибкой; класс должен быть подклассом.
Заключение
simplexml_import_dom() позволяет выполнять точную работу с расширением DOM, а затем читать или сериализовать результат с помощью лёгкого синтаксиса SimpleXML. Функция естественным образом сочетается с dom_import_simplexml() для обратного перехода к DOM. Когда ваши данные уже находятся в DOM-дереве, эта функция — самый чистый способ продолжить работу с доступом через свойства объекта вместо многословных вызовов DOM.