Расширения SAX и DOM XML
Для работы с XML -документами можно использовать язык PHP. В PHP для этого существует два модуля, реализующие два разных стандарта обработки XML -данных: SAX (Simple API for XML) и DOM (Document Object Model).
Стандарт SAX (http://www.saxproject.org) не является стандартом W3C и описывает метод обработки XML -документов для получения из них данных. То есть этот метод обработки XML -документов позволит только прочитать данные из XML -документа, и не более того. Создавать и изменять XML -документы с его помощью невозможно.
SAX основан на так называемом событийном программировании. Его особенность заключается в том, что вы предоставляете парсеру XML набор собственных функций, которые будут заниматься обработкой различных типов XML -данных ( элементов (тегов), текста и т.п.), а парсер затем будет сам вызывать ваши функции в процессе обработки XML -документа, передавая им найденные данные. Функции будут вызываться в той же последовательности, в которой соответствующие данные располагаются в XML -документе.
Другим стандартом для обработки XML -данных является DOM – стандарт W3C, спецификацию которого можно найти на сайте консорциума (http://www.w3c.org/DOM). В отличие от SAX, этот метод позволяет производить любые операции с XML -данными в достаточно удобной форме – представляя XML -документ как дерево объектов.
Модуль, реализующий этот стандарт, называется DOM XML. Он не входит в основной набор модулей PHP, но может быть установлен как расширение. API этого модуля старается как можно более точно следовать стандарту DOM level 2. Кроме того, существует множество дополнительных функций. Эти функции включены для совместимости с предыдущими версиями расширения, и использовать их в новых скриптах не рекомендуется. Кроме того, у расширения DOM XML есть проблемы с русской кодировкой. Парсер обрабатывает текст только в кодировке UTF-8, поэтому текст нужно каждый раз перекодировать с помощью функции iconv. Отсюда и необходимость установки расширения iconv вместе с DOM XML.
Модуль DOM XML является мощным и удобным в использовании средством обработки XML -документов. В данной лекции мы будем рассматривать именно его.
Установка расширения DOM XML
Для того чтобы установить расширение DOM XML, нужно сделать следующее.
- В файле настроек PHP (php.ini) раскомментировать строку, касающуюся этого расширения ( extension=php_domxml.dll для Windows, либо extension=php_domxml.so для Linux-платформ).
- Скопировать файл расширения ( php_domxml.dll или php_domxml.so ) в папку, где находятся расширения ( extension_dir ).
- Подключить расширение iconv так же, как в пунктах выше (иногда это расширение устанавливается автоматически вместе с domxml ).
- Скопировать дополнительные библиотеки в системную папку system (Windows 98) или system32 (WindowsNT/2000/XP). В первую очередь это библиотеки libxml2 и iconv, затем libxslt, libexslt и zlib.
- Перезапустить сервер.
Следует проверить, правильно ли установлена переменная extension_dir в файле настройки php.ini. Если она не указывает на директорию, где находятся библиотеки расширений PHP, то ни одно из расширений подключить не удастся.
Чтобы проверить, установилось ли расширение, можно создать простейший скрипт, который будет выводить все настройки PHP-интерпретатора (это делает функция phpinfo() ). Другой вариант – попробовать использовать какую-нибудь функцию из данного расширения. Например, можно попробовать получить версию используемой библиотеки libxml с помощью функции domxml_version() . Но этот способ не очень хорош, поскольку расширение экспериментальное (это значит, что некоторые функции в каких-то определенных условиях могут и не работать), да и функции еще надо изучить, прежде чем их использовать.
<?
// выводит информацию о настройках PHP
phpinfo();
// отображает используемую версию
// библиотеки libxml
echo domxml_version();
?>
Пример 14.1. Проверка, установлено ли расширение DOM XML (html, txt)
Взаимодействие PHP и XML посредством DOM XML
Что происходит, если взаимодействие PHP и XML осуществляется с помощью объектной модели стандарта DOM? Модуль DOM XML определяет в PHP несколько классов, таких как DomNode, DomDocument,DomElement, DomText и DomAttribute, большинство из которых идут из ядра стандарта DOM. Почти для всех классов (в частности, для перечисленных выше) класс DomNode является родительским, поэтому его свойства и методы наследуются всеми остальными классами.
Если рассмотреть произвольный XML -документ, то классу DomDocument будет соответствовать сам этот документ, классу DomElement – каждый XML -тег, классу DomAttribute – атрибуты тегов, а классу DomText – содержание XML- элементов. В то же время классу DomNode будет соответствовать каждый из перечисленных элементов XML -документа.
Рассмотрим коллекцию, содержащую описания персон. Если каждую из них мы описываем с помощью таких характеристик, как фамилия, имя, дата рождения и электронный адрес, то структураколлекции » Личности «, где хранится информация обо всех известных нам персонах, может быть представлена следующим образом.
Пример 14.2. Коллекция Личности в виде XML-файла (persons.xml) (html, txt)
В дальнейшем, приводя примеры, мы будем использовать этот файл.
Нам необходимо научиться читать, добавлять, изменять и искать информацию, находящуюся в XML -файлах.
Перевод данных XML-файла в объекты и классы PHP
Первое, что нужно сделать, если мы хотим работать с XML -данными в PHP при помощи расширения DOM XML, это перевести имеющиеся данные в объекты и классы DOM. Это можно сделать несколькими способами.
- С помощью функции domxml_open_mem .
Синтаксис:
object domxml_open_mem (string str)
В качестве параметра эта функция принимает строку str, содержащую XML -документ. Результатом ее работы является объект класса, называемого DOMDocument.
- С помощью функции domxml_open_file .
Синтаксис:
object domxml_open_file (string filename)
Эта функция обрабатывает XML -файл, имя которого задается параметром filename, и переводит его в объект класса DOMDocument. Доступ к файлу производится только на чтение.
Такие функции, как domxml_open_mem() и domxml_open_file() , как правило, нужно вызывать перед вызовом любых других функций, связанных с расширением DOM.
Эти функции преобразуют XML -файл в дерево объектов. К таким объектам можно обращаться с помощью различных методов. В частности, для выделения корневого элемента используется метод DomDocument->document_element() .
Еще существует функция domxml_new_doc(string version) , которая создает новый пустой XML -документ. Ее параметром является номер версии создаваемого документа. Но ее мы касаться не будем, а будем считать, что XML -файл уже создан.

Пример 14.3. Перевод XML-файла в дерево объектов PHP и выделение корневого элемента (html, txt)
Итак, каждому элементу XML -файла мы поставили в соответствие какой-то объект. Теперь нужно научиться перемещаться по дереву объектов и обращаться с этими объектами: получать и изменять их значения, находить их потомков и предков, удалять объекты.
Обход дерева объектов
Для получения значения текущего узла (вне зависимости от его типа) используют метод DomNode->node_value() или DomNode->get_content() для получения содержимого узла.
Для получения значения атрибута используется метод DomElement->get_attribute (attr_name) . А метод DomNode->child_nodes() возвращает массив потомков данного узла.
Для того чтобы сделать обход дерева объектов, полезно еще уметь различать объекты по типам, т.е. определять, является ли узел элементом (тегом), текстом, атрибутом и т.п. Для этого используются специальные константы. XML_ELEMENT_NODE определяет, является ли узел элементом, XML_ATTRIBUTE_NODE определяет, является ли узел атрибутом, и XML_TEXT_NODE определяет, является ли узел куском текста. Эти константы имеют целочисленные значения 1, 2 и 3 соответственно. Использование этих констант полезно, поскольку переводы строки, применяемые для удобочитаемости XML -файлов, тоже становятся узлами.

Пример 14.4. Обход дерева XML (html, txt)
Итак, мы научились обходить дерево XML. Теперь можно попытаться что-нибудь найти в XML -файле. Правда, делать это не совсем удобно опять же из-за переносов строк, которые мы использовали при написании XML -файла. Пусть наш XML-файл записан в строку, а точнее, в нем есть следующая строка:
…
<person id=»20″>
<name>
<first>Иван</first>
<last>Иванов</last>
</name>
…
Тогда в наш предыдущий пример вставим (после вывода на экран полученных массивов) строчку для поиска электронного адреса Ивана Иванова.
…
$str = $currentPers[«email»];
if ($currentPers[«name»] ==
«Иван Иванов» )
echo «Здравствуйте, Иван! » .
«Ваш e-mail $str»;
…
Добавление новых элементов в XML-документ
Далее разберем задачу, как можно добавить в нашу базу данных новую личность средствами php.
Сначала нужно скопировать описание личности (считаем, что все личности описываются с помощью стандартного набора характеристик, как в файле persons.xml ). Это делается с помощью метода DomNode->clone_node() . Таким образом, мы клонируем элемент <person> и все его внутренние элементы (содержание тегов не копируется).
Потом можно установить какие-нибудь значения для элементов описания личности. Например, задать имя человека, дату его рождения и т.п. В конце нужно записать полученное описание личности в качестве потомка корневого элемента в дерево DOM с помощью метода DomNode->append_child(new_node) , где в качестве параметра передается созданный объект (новый узел).
В PHP до версии 4.3 перед добавлением потомка к узлу с помощью данной функции этот потомок сначала копировался. Таким образом, новый узел являлся новой копией, которая могла изменяться без изменения узла, переданного как параметр в эту функцию. В более поздних версиях PHP новый узел удаляется из существующего контекста, если он уже есть в дереве. Такое поведение соответствует спецификациям W3C.
Для удаления узла можно воспользоваться методом, применив его к узлу, который требуется удалить, т.е. DomNode->unlink_node() .

Пример 14.5. Добавление описания новой личности в каталог (html, txt)
Заключение.
Итак, мы изучили ряд функций, позволяющих манипулировать данными, хранящимися в XML -формате. Это, конечно же, далеко не полный перечень существующих функций. В версии PHP5 он значительно усовершенствован и в большей степени соответствует стандарту DOM. Тем не менее знание приведенных здесь основных функций может оказаться полезным при решении конкретных прикладных задач.


Оставить комментарий