Генерация XML в PHP 14 июля 08
Рассматривая примеры генерации XML-выгрузок от различных украинских маркетов (не буду никого смущать прямыми ссылками), удивлен тем, что многие используют обыкновенную шаблонную методику, вроде:
<item id=”<?=$o->productID?>” top=”0”> <name><?=to_xml($o->name)?></name> <price><?=$o->price?></price> <categoryId><?=$o->categoryID?></categoryId> <description><?=to_xml($o->description)?></description> <url><?=to_xml(”http://myshop.kiev.ua/index.php?productID=”.$o->productID)?></url> <image><?=to_xml(”http://myshop.kiev.ua/pictures/”.$o->image)?></image> </item>
Я уже молчу о том, что в данном конкретном примере присутствуют short_open_tags.
Но почему не использовать встроенные в PHP 5 DOM-классы? Это дает нам такие преимущества (навскидку):
- гарантированная валидность результата (и соответствие DTD, если его указать)
- автоматическое форматирование (
$dom -> formatOutput = true;) - автоматическое преобразование кодировки – достаточно указать нужную в заголовке файла.
Посмотрим на генерацию того же фрагмента XML средствами DomDocument:
$item = $dom_items -> appendChild( $dom->createElement('item'));
$item -> setAttribute('id', $o->productID);
$item -> setAttribute('top', '0');
$item -> appendChild( $dom->createElement('price', $record['price']));
$item -> appendChild( $dom->createElement('categoryId', $o->categoryID));
$item -> appendChild( $dom->createElement('name',htmlspecialchars($o->name)));
$item -> appendChild( $dom->createElement('description',
htmlspecialchars($o->description)));
$item -> appendChild( $dom->createElement('url',
htmlspecialchars("http://myshop.kiev.ua/index.php?productID=".$o->productID)));
$item -> appendChild( $dom->createElement('image',
htmlspecialchars("http://myshop.kiev.ua/pictures/".$o->image)));
Разве этот код не понятнее и структурнее, чем tag soup из первого примера? Да, писать придется немного больше, зато ты никаким образом не отдашь в XML неэскейпленные символы, незакрытые теги и прочий мусор.
Немного теории
Для начала все, что надо знать – это пять функций. Почитай их описание в PHP Manual:
$dom = DOMDocument::loadXML('<?xml version="1.0" encoding="utf-8"?><root_node/>');– создает документ вместе с корневым элементом$dom -> documentElementDOMElement::setAttribute('name', $value)– устанавливает атрибутDOMElement::appendChild( $dom->createElement('name', [$text]) )– создает в документе элемент<name>text</name>и добавляет в другой элемент$dom->saveXML()– отдает всю эту красоту в виде строки
Все, дальше курим маны и больше никогда, никогда, никогда не выводим XML шаблонами.

Подписаться на RSS

Комментарии
Если надо только сгенерить XML, то ИМХО правильнее будет использовать XMLWriter, т.к. генерация Dom дерева жрет больше ресурсов.
+1 к комментарию Alex.
Не смотря на минусы (кстати у него есть и плюсы) первого предложенного метода, второй тоже далек от идела удобства.
Во втором методе теряется главное – связь между структурой кода и структурой данных, что я воспринимаю как недальновидность разработчика (через 2 года поди разбери структуру этого XML глядя на код)
Лично меня уже тошнит от этих w3c-шных createElement/setAttribute/appendChild.
Структуру сохранить не сложно, если разделять генерацию всего документа на отдельные методы.
Касательно разбирания структуры – предлагаю сопровождать любой генерирующий XML код либо DTD, либо RelaxNG-схемой – как минимум для юнит-тестов.