PHP и XML

Продолжаю свою подготовку к Zend exam. Zend Certification Study Guide (могу поделиться, кому нужно :), текущая тема – XML and Web Services.

PHP 5 предоставляет отличные средства для работы с XML документами. Одной из этих библиотек является SimpleXML.
Все объекты, созданные SimpleXML, являются экземплярами класса SimpleXMLElement. Рассмотрим на примере загрузку XML документа. У нас есть XML файл с информацией о продуктах в магазине следующего содержания (store.xml):

Загрузить XML документ можно несколькими способами. Первый способ предполагает использование функций simplexml_load_string и simplexml_load_file, которые возвращают объект SimpleXMLElement.

Второй способ – использование конструктора объекта SimpleXMLElement.

Пожалуй, самым интересным является последний способ. Загрузка XML через конструктор позволяет задать некоторые опции (второй параметр конструктора): все эти флаги начинаются на “LIBXML_”. При их помощи можно убрать пустые элементы (LIBXML_NOBLANKS), заменить entities (LIBXML_NOENT), отключить вывод ошибок и предупреждений (LIBXML_NOERROR), проверить загружаемый документ на валидность, используя DTD схему (LIBXML_DTDVALID) – подробное описание можно найти в мануале – глава “LXXVI. libxml Functions”.

После загрузки XML документа мы можем получить доступ к его элементам. Все элементы конвертируются в свойства объекта SimpleXMLElement, все атрибуты – в ассоциативный массив (имена элементов и атрибутов регистрозависимые):

Кроме этого SimpleXML предоставляет средства, при помощи которых можно узнать список всех элементов и атрибутов (и их имена).

SimpleXMLElement::children()
SimpleXMLElement::attributes()
SimpleXMLElement::getName()

Таким образом можно вывести XML, не зная имен элементов и атрибутов.

SimpleXML также позволяет выполнять запросы XPath (метод SimpleXMLElement::xpath(xpath_expression)). Данный метод возвращает массив элементов SimpleXMLElement. Например, мы можем получить названия всех товаров:

или массив id всех товаров:

Следует отметить, что XPath всегда возвращает массив объектов SimpleXMLElement (даже если результатом запроса является один элемент).

Изменение XML документа

В ранних версиях php (до 5.1.3), у SimpleXML не было возможности добавлять элементы и атрибуты в XML документы. Можно было только изменять существующие значения, но единственным способом добавления новых элементов и атрибутов было экспортирование SimpleXML объекта в DOM (используя функцию dom_import_simplexml). Добавление производится при помощи DOM (методы объекта DomDocument->create_element, DomDocument->create_attribute и др.). После этого DOM документ экспортируют обратно в SimpleXML (simplexml_import_dom). Согласитесь, не очень удобно.
С версией php 5.1.3 у SimpleXML появилось два новых метода SimpleXMLElement::addChild() и SimpleXMLElement::addAttribute().
Эти методы принимают 3 параметра – имя элемента (атрибута), его значение и пространство имен (опционально).
Рассмотрим на примере добавление нового продукта в наш документ store.xml:

В последней сроке используется метод SimpleXMLElement->asXML([filename]). Данный метод возвращает XML строку на основе текущего SimpleXMLElement, если определен параметр filename – то XML строка сохраняется в файл.

С XML можно работать при помощи DOM, но это будет рассмотрено уже в следующей статье.

  • Помоему самое большое неудобство с которым я встретился была невозможность распечатать полученное дерево/массив через print_r.. Показывался очень ограниченно именно объект simplexml. Как-то выкрутился в итоге, видимо он читает по ходу цикла парсинга а не за раз всё, поэтому ест меньше памяти

  • Можно занаследовать от SimpleXML класс и написать для него функцию __toString().
    Вполне хорошее решение, хоть и не print_r

  • Слуушай) А когда ты будешь сдавать? Если ты вдруг из Питера – пойдем вместе? Я тоже хочу сдать)

    2275520 моя аська, стучись. ток там спамбот 2+2 спросит.)

  • admin

    @CharnaD:
    К сожалению, я не из Питера. Харьков.

  • андр

    а, как заменить существующий элемент новым?

  • все хорошо, а вот вопрос.

    как удалить из симпл хмл элементы? :))

    есть решение?

  • Удалять элементы можно с помощью unset(), а вот как удалять атирбуты – для меня пока загадка….

  • {root}->attributes()->null;

  • Есть отличная функция http://php5lab.com/blog26.html