СтатьиPHP5: как работать с XML через SimpleXMLЕсли вы разрабатываете серьезное интернет-приложение или корпоративную систему, скорее всего, вы будет иметь дело с XML. За последнее время это самая популярная технология, и вы просто должны были слышать о ней, поэтому не будем останавливаться на самой концепции XML, а сразу перейдем к сути. При создании скриптов на РНР неоднократно приходится сталкиваться с необходимостью работы с данными в XML-формате, причем очень часто эта работа совершенно тривиальна. Чтение данных, простая выборка (какого-то конкретного узла или значения), изменение данных – все эти функции, с одной стороны, очень просты при описании, но достаточно сложны, когда приходится заниматься этим в реальности. В РНР, начиная с версий 4.х, для программистов всегда доступны несколько расширений, которые позволяют произвольно манипулировать XML-данными. Например, в версии 4.3.х присутствует расширение DOM XML, используя которое можно преобразовать XML в объектную модель и работать с ней согласно спецификации DOM. Иерархия тегов в таком случае будет транслирована в набор объектов РНР, с которыми можно работать через встроенные функции. На низком уровне это расширение использует популярный XML-парсер libxml, взятый из другого OpenSource-проекта – GNOME. Хотя сам формат XML достаточно простой, но вот работа с ним на программном уровне гораздо сложнее – DOM XML в РНР представляет в распоряжение программиста очень много функций, переменных и флагов, так что разбираться со всем этим приходится не один день. Альтернативой DOM XML может быть применение расширения XMLParser, работающего на основе парсера expat, разработанного Джимом Кларком (James Clark). Работа через XMLParser намного проще и открывает перед разработчиком широкие возможности. Хотя если вам надо не только просто разбирать XML, но и проверять их на соответствие стандарту или определенной схеме данных, тут уже придется использовать другие расширения.
Кроме этих стандартных расширений, на сайте PHP Classes можно найти огромное количество отдельных классов для решения частных задач, связанных с обработкой и проверкой XML, – например, DOMIT XML parser, SAXY XML parser и другие. Но что же делать, если надо производить какие-то простые действия над XML, когда не надо привлекать на помощь огромные интерфейсы и сложнейшие библиотеки? Для таких случаев в РНР 5.0 появился новый модуль, значительно упрощающий жизнь разработчика. Название его говорит само за себя — SimpleXML.
Если вы работаете с РНР версии 5.0 или выше, то поддержка SimpleXML у вас включена по умолчанию, если это не так, используйте опцию конфигурации
Для начала работы необходимо загрузить XML-данные. Это может быть как файл, так и просто строковая переменная, содержащая XML-код. Если вы используете параллельно и DOM XML, то можете сразу загрузить DOM-модель документа в SimpleXML (и потом выгрузить ее обратно для продолжения работы). Давайте рассмотрим работу с SimpleXML на реальном примере, который позволит продемонстрировать некоторые особенности и нюансы работы расширения. Воспользуемся реальным XML-кодом, частью XML-RPC-ответа поискового сервера Yandex (http://xml.yandex.ru), в котором содержатся описания найденных в ответ на запрос документов. Вот пример XML-кода, который описывает один документ (результат поиска):
Загрузить этот документ можно функцией. Если документ представлен в виде файла, то код будет иметь вид
А теперь сразу расскажу про одну особенность этого кода. В примерах на php.net встречается фрагмент, когда обычный XML-код загружается в SimpleXML. Имеется в виду, что это может быть не код, строго оформленный по спецификации XML, а только сама структура, например
Хорошо, документ загружен и преобразован в доступную для работы форму. Но как конкретно SimpleXML его обрабатывает? Все части XML-кода (узлы, или
На рисунке ниже показана структура, созданная после загрузки нашего примера. Основной элемент, класс
Теперь о практическом применении полученной информации. Как получить доступ к информации, хранимой в XML-структуре? Очень просто. Доступ к отдельным элементам и их значениям можно получить, указывая на конкретный элемент (ведь это всего лишь обычный массив). Например, URL документа можно получить так: $xml_node = $res->doc; echo $xml_node->url[0]; или без создания отдельного объекта, напрямую адресуясь к нужному элементу: echo $res->doc->url[0]; или так: echo $res->doc->url; Для перебора всех дочерних элементов можно в цикле получить доступ к каждому дочернему узлу и производить над ними нужные операции. Именно так в моем коде обрабатывается ответ сервера "Яндекс" – в цикле я получаю необходимый узел и уже его использую для извлечения данных. foreach ($xml as $simple_node) { echo "URL документа: " . $simple_node->url[0]; }
Кроме доступа к отдельным узлам и получения их значения вы можете получить сразу весь XML-код узла либо всех дочерних элементов. Для этого echo $xml->asXML(); // возвращает строку с содержимым XML-документа echo $xml->doc->asXML(); // возвращает строку с содержимым узла <doc>
Но обратите внимание, что конструкция
Не думайте, что простота SimpleXML означает примитивность. Поддерживаются и более мощные возможности, к примеру адресация элементов с помощью специального языка XPath. XPath — это специальный язык (метод) для адресации частей XML-документов и построения ссылок на конкретные узлы или элементы в иерархии XML. Сама по себе спецификация XPath достаточно сложная, но нам пока пригодятся самые базовые сведения. Функция Например, URL можно найти, применив для отбора следующий код: $xml_node = $res->xpath("/group/doc/url");
Выражение XPath
Для получения любого дочернего узла в виде массива можно воспользоваться функцией $xml_node = $res->doc->children(); echo $xml_node[0]; // выводит URL, первый (с индексом 0) элемент echo $xml_node[5]; // выводит кодировку, шестой дочерний элемент узла <doc> В заключение расскажем еще про изменение значений элементов. Сделать это так же просто, как и прочитать соответствующее значение. Сначала необходимо найти нужный элемент, а потом просто присвоить ему новое значение: $xml->doc->url = "http://test.com/"; // меняет URL в документе на новый
Но необходимо быть внимательным. Если в примере узел $xml->doc = "это просто строка"; echo var_dump($xml); echo $xml->asXML();
Тут также вас поджидает некоторая проблема — если вы заменяете какой-либо узел или значение элемента на строку с кириллическими символами, то функция
Как видно на рисунке, функция Проводить очень сложную обработку XML-документов при помощи SimpleXML все же сложно, да и серьезные приложения, как правило, требуют более мощных инструментов, например валидацию XML при помощи схем или DTD. Но для простых работ вроде чтения/записи SimpleXML может обеспечить получение доступа к отдельным элементам и их изменение, причем достаточно просто. А поддержка мощного языка адресации XPath позволяет с легкостью манипулировать отдельными частями любого XML-документа. Автор: Александр Лозовюк |
||