// Создание объекта документа из текстовой строки $xmldoc = domxml_open_mem(<?xml version=1.0 encoding=windows-1251?>);
// Cсылку на корневой узел документа записываем в переменную $my_root (название //переменной значения не имеет). $my_root = $xmldoc->document_element();
// В массив $children записываются все потомки узла my_root. $children = $my_root->child_nodes();
// Уничтожается первый потомок (узел something) $children[0]->unlink_node();
// Создаётся новый узел под названием new и записывается в переменную $new $new = $my_root->append_child($xmldoc->create_element(new));
// К этому узлу добавляется потомок — текстовый узел $new->append_child($xmldoc->create_text_node(iconv(windows-1251, UTF-8, Это содержимое нового узла XML-документа.)));
print($xmldoc->dump_mem());
?>
в результате получится такой XML-документ:
<?xml version=1.0 encoding=windows-1251?> <my_root><new>Это содержимое нового узла XML-документа.</new></my_root>
Кстати, если изменить исходный XML-документ на такой:
<?xml version=1.0 encoding=windows-1251?> <my_root><something>Нечто</something> <new>Это содержимое нового узла XML-документа.</new></my_root>
Предоставляю вам возможность догадаться, почему это произошло.
Конечно же, приведённые примеры — самое простое из того, что можно делать в DOM XML. Кроме построения нового это и самые хитрые преобразования документа, и XSL-трансформация при помощи библиотеки libxslt, не уступающей в функциональности Sablotron, а в скорости превосходящей его в два раза. Перед нами открываются огромные возможности по работе с документом, проблема — как организовать и систематизировать эту работу.
На ум приходит следующая схема преемника классов шаблонов: вызывается скрипт, который открывает стандартный XML-файл и включает буферизацию данных. Все скрипты тупо выдают XML-данные в print. Вызывается второй скрипт, который останавливает буферизацию, берёт данные из буфера, дописывает к ним в начале "<?xml version="1.0" encoding="windows-1251"?><root>" и "</root>" в конце, затем преобразует в объект DOM, открывает корневой элемент и берёт всех массив потомков. Полученные узлы вставляет в основной XML-документ (который тоже открыт как объект), результат преобразует через XSLT и выдаёт пользователю.
На этом заканчиваем краткое описание DOM XML и переходим к классу sql2xml. Класс SQL2XML
Вся функциональность, которая нужна для преобразования результатов SQL-запросов в XML, есть в этом классе. Для соединения с базой данных класс использует либо существующее соединение класса PEAR::DB, либо своё собственное (точнее, он создаёт в себе объект класса DB). Из результата запроса строится XML-дерево. Пример из руководства по классу:
mysql> select * from bands; +----+--------------+------------+-------------+-------------+ id name birth_year birth_place genre +----+--------------+------------+-------------+-------------+ 1 The Blabbers 1998 London RocknRoll 2 Only Stupids 1997 New York Hip Hop +----+--------------+------------+-------------+-------------+
mysql> select * from albums; +----+---------+------------------+------+-----------------+ id bandsID title year comment +----+---------+------------------+------+-----------------+ 1 1 BlaBla 1998 Their first one 2 1 More Talks 2000 The second one 3 2 All your base... 1999 The Classic +----+---------+------------------+------+-----------------+
Это набор данных. А теперь вызов класса и результаты работы. php-код:
<?php include_once(XML/sql2xml.php); $sql2xmlclass = new xml_sql2xml(mysql://username:password@localhost/xmltest); $xmlstring = $sql2xmlclass->getxml(select * from bands); ?>
Результат выводится и в текстовом виде, и как DOM-объект (что весьма удобно при генерации документов через DOMXML). Так же можно из всего XML-дерева выдернуть одно значение при помощи выражения XPath. Ещё очень хорошая особенность: раз уж строятся деревья, и всё оперируется в XML, почему бы запросы с объединением "один-ко-многим" не делать в виде вложенных друг в друга узлов <row>. php-код:
<?php include_once(XML/sql2xml.php); $sql2xml = new xml_sql2xml(mysql://username:password@localhost/xmltest); $xmlstring = $sql2xml->getxml(select * from bands left join albums on bands.id = bandsID); ?>
Впрочем, если вы хотите получить обычный результат запроса, это свойство можно отключить. Если имена узлов для результата и для ряда вас не устраивают, можно их поменять. Если вас не устраивает формат (всё в текстовых узлах, а не, например, в атрибутах), можно преобразовать полученный DOM-объект в нужный вам. На мой взгляд, этого не понадобится, поскольку если на сайте до этого уже использовался XSLT, исправить XSL-файл не представляет особой сложности.
Итак, класс вполне пригоден к использованию. Если он вас чем-то не устраивает, можно, глядя на существующий, написать свой собственный. Исправлять данный класс вполне можно, поскольку манипуляции с DOM-объектами не намного сложнее внутреннего устройства классов шаблонов. Я для себя исправил ошибки call-time pass-by-reference в классе версии 0.3 (версия 0.3.1 — это как раз мой багфикс) а так же заменил старые не поддерживаемые функции и конструкции DOM XML на новые. Сейчас работаю над тем, как справиться с проблемой кодировки документа (объект документа там создаётся функцией domxml_new_doc, а для создания из текстовой строки требуется основательно переделать существующую в классе sql2xml функцию).