Разработчику. Сборник рецептов PHP
Задавайте вопросы

Генерация XML с применением DOM

Вернуться назад

Задача

Необходимо сгенерировать XML, используя более высокий уровень организации данных, чем в случае применения операторов вывода (print) и циклов.

Решение

Используйте расширение PHP DOM XML для создания и заполнения соответствующего DOM-объекта, затем вызовите функцию dump_mem() или dump_file() для того, чтобы сгенерировать корректный (well-formed) XML-документ:

// создаем новый объект документ
$dom = domxml_new_doc('1.0');

// создаем корневой элемент, <book>, и добавляем его в документ
$book = $dom->append_child($dom->create_element('book'));

// создаем элемент title и присоединяем его к переменной элементу $book
$title = $book->append_child($dom->create_element('title'));

// создаем текст и атрибут cover для элемента $title
$title->append_child($dom->create_text_node('PHP Cookbook'));
$title->set_attribute('cover', 'soft');

// создаем и добавляем элементы author в переменную элемент $book
$sklar = $book->append_child($dom->create_element('author'));

// создаем и добавляем текст для элемента author
$sklar->append_child($dom->create_text_node('Sklar'));

// повторяем эти действия для второго элемента authors
$trachtenberg = $book >append_child($dom->create_element('author'));
$trachtenberg->append_child($dom->create_text_node('Trachtenberg'));

// печатаем полностью отформатированную версию документа DOM в форме XML
echo $dom->dump_mem(true);

Результат работы примера:

<?xml version="1.0"?>
<book>
       <title cover="soft">PHP Cookbook</title>
       <author>Sklar</author>
       <author>Trachtenberg</author>
</book>

Обсуждение

Одиночный компонент документа называется узлом. Существует масса различных типов узлов, из которых чаще других используются три-элемент, атрибут и текст. Рассмотрим пример:

<book cover="soft">PHP Cookbook</book>

С позиции расширения DOM XML, элемент book имеет тип XML_ELEMENT_NODE, пара «имя-значение» cover="soft" относится к типу XML_ATTRIBUTE_NODE, а строка PHP Cookbook – к типу XML_TEXT_NODE (*).

Для DOM-анализа PHP использует библиотеку libxml, разработанную для проекта Gnome. Ее можно загрузить с http://www.xmlsoft.org. Что-бы подключить и активировать эту библиотеку, необходимо сконфигурировать PHP с параметром --with--dom.(**)

Методы DOM XML в версии PHP 4.3 применяются согласно следующему шаблону. Вы создаете объект как узел-элемент или как узел-текст, а затем помещаете его в то место (узел типа элемент) дерева, где он долен находиться. Перед тем как создавать элементы дерева, необходимо создать сам документ, передав конструктору объекта единственный параметр – версию XML:

$dom = domxml_new_doc('1.0');

Теперь можно создавать новые элементы, принадлежащие документу. Несмотря на то что все узлы-элементы имеют смысл лишь внутри документа, операция присоединения (подключения) узла к документу должна быть выполнена явным образом:

$book_element = $dom->create_element('book');
$book = $dom->append_child($book_element);

Здесь мы создаем новый элемент book и назначаем его объекту $book_element. Для того чтобы создать корневой элемент документа, мы должны добавить наш новый объект (в качестве дочернего) к объектудокументу $dom. Результатом работы метода append_child() будет новый объект, обладающий местоположением (включенный в документ) в объекте DOM.

Все узлы создаются с помощью вызова метода объекта $dom. После создания узел может быть добавлен к любому элементу дерева. Элемент,чей метод append_child() мы вызываем, определяет местоположение узла в дереве. В предыдущем случае $book_element добавлялся к $dom. Элемент, добавленный к $dom, представляет узел верхнего уровня документа, или корневой узел.

Можно также добавить новый дочерний элемент в $book. Поскольку $book представляет собой дочерний элемент документа $dom, новый элемент по аналогии будет внуком документа $dom:

$title_element = $dom->create_element('title');
$title = $book->append_child($title_element);

С помощью вызова $book->append_child() этот фрагмент кода помещает элемент $title_element под элементом $book.

Для добавления текста внутрь тегов <title></title> создайте текстовый узел с помощью функции create_text_node() и добавьте его к $title:

$text_node = $dom->create_text_node('PHP Cookbook');
$title->append_child($text_node);

Элемент $title уже добавлен к документу, поэтому нет необходимости добавлять его в $book повторно.

Порядок, в котором дочерние элементы добавляются к узлам, не важен. Следующие четыре строчки, которые сначала добавляют текстовый узел к $title_element, а затем к $book, эквивалентны предыдущему коду:

$title_element = $dom->create_element('title');
$text_node = $dom->create_text_node('PHP Cookbook');

$title_element->append_child($text_node);
$book->append_child($title_element);

Для добавления атрибута надо вызвать метод set_attribute() нужного узла, передав имя атрибута и его значение в качестве аргументов:

$title->set_attribute('cover', 'soft');

Если теперь напечатать элемент title, он будет выглядеть примерно так:

<title cover="soft">PHP Cookbook</title>

Теперь можно вывести весь документ в виде строки или в файл:

// помещаем строковое представление XML-документа в $books
$books = $dom->dump_mem();

// записываем XML-документ в файл books.xml
$dom->dump_file('books.xml', false, true);

Единственный параметр, который принимает метод dump_mem(), – это необязательное логическое значение. Пустое значение (или false) означает «вернуть результат как одну длинную строку». Значение true порождает удобно отформатированный документ XML, в котором дочерние узлы выводятся с соответствующими отступами, например:

<?xml version="1.0"?>
<book>
       <title cover="soft">PHP Cookbook</title>
</book>

Методу dump_file() можно передавать до трех значений. Первое обязательное значение – это имя файла. Второе значение определяет, должен ли файл сжиматься с помощью gzip. Последнее значение представляет ту же самую опцию форматирования, что и в методе dump_mem().


(*) Здесь прослеживается прямая аналогия с базовыми компонентами языка XML. Ключевым компонентом XML является элемент (изолированная с помощью тегов область данных). Элементы могут разбиваться на подэлементы и выполняют роль связывания имен-меток и других свойств с данными. Кроме того, элементы могут включать пары «имя-значение», именуемые атрибутами.

(**)  При работе в ОС Windows надо скопировать соответствующую библиотеку (файл с расширением .DLL) из подкаталога \DLLS того каталога, в который установлен PHP, в подкаталог \SYSTEM32 каталога %Windows%. Для пользователей PHP версии не выше 4.2 это библиотека ibxml2.dll, а для пользователей версии не ниже 4.3.0 – библиотека iconv.dll.

Вернуться назад

Рейтинг@Mail.ru

Яндекс.Метрика

Индекс цитирования

Рейтинг Сайтов ДОСКИ.РУ