Задача
Необходимо сгенерировать XML-документ. Например, требуется предоставить XML-версию данных для анализа другой программе.
Решение
Надо в цикле пройти по всем данным и вывести их, заключив в соответствующие теги XML:
header('Content-Type: text/xml');
print '<?xml version="1.0"?>' . "\n";
print "<shows>\n";
$shows = array(array('name' => 'Simpsons',
'channel' => 'FOX','start' => '8:00 PM',
'duration' => '30'),
array('name' => 'Law & Order',
'channel' => 'NBC',
'start' => '8:00 PM',
'duration' => '60'));
foreach ($shows as $show) {
print " <show>\n";
foreach($show as $tag => $data) {
print " <$tag>" . htmlspecialchars($data) . "</$tag>\n";
}
print " </show>\n";
}
print "</shows>\n";
Обсуждение
Вывод XML вручную требует множества вложенных циклов foreach, поскольку выполняются итерации по массивам. Кроме того, здесь есть несколько хитрых нюансов. Во-первых, необходимо вызвать функцию header(), указать корректный заголовок Content-Type для нашего документа. Наша программа отправляет данные в формате XML, а не в HTML, поэтому заголовок должен указывать тип содержимого как text/xml.
Далее, в зависимости от значения параметра настройки short_open_tag, попытка напечатать объявление XML может непроизвольно включить обработку PHP. Символы <? элемента <?xml version="1.0"?> совпадают с краткой формой открывающего тега PHP-кода. Для вывода объявления в броузере необходимо либо запретить в конфигурации краткую форму тега, либо выводить эти строки из PHP. В нашем «Решении» мы выбрали последний из этих вариантов.
И наконец, сами элементы должны быть превращены в escape-последовательности. Например, символ & при показе строки Law & Order должен быть выдан в виде &. Данные преобразуются в escape-последовательности посредством функции htmlspecialchars().
Результат работы примера, приведенного в разделе «Решение», выглядит так:
<?xml version="1.0"?>
<shows>
<show>
<name>Simpsons</name>
<channel>FOX</channel>
<start>8:00 PM</start>
<duration>30</duration>
</show>
<show>
<name>Law & Order</name><channel>NBC</channel>
<start>8:00 PM</start>
<duration>60</duration>
</show>
</shows>