WebClub - Всероссийский Клуб Веб-разработчиков
WebClub.RU » Советы » Чтение XML-данных в PHP с использованием SAX

Чтение XML-данных в PHP с использованием SAX


Дата публикации: 14-01-2008

Для того, чтобы показать, как использовать имеющиеся в  PHP модули для работы с XML-данными возьмем реальный пример - колонка новостей, хранящаяся в XML файле.

Файл news.xml, в котором хранятся новости:

<?xml version="1.0"?>
<newsLine>
    <news date="1.1.2002">
        <title>title 1</title>
        <text>news text 1</text>
    </news>
    <news date="5.1.2002">
        <title>title 2</title>
        <text>news text 2</text>
    </news>
    <news date="10.1.2002">
        <title>title 3</title>
        <text>news text 3</text>
    </news>
</newsLine>

Файл test.php, выполняющий парсинг news.xml для получения новостей:

<?php
$news = array();        // В этом массиве будут храниться новости,                        // полученные из XML файла$currentNews = null;    // Текущая новость. Используется в процессе                        // импорта данных$index = null;          // Текущий индекс в массиве новостей.                        // Используется в процессе импорта данных// Функции, описанные ниже, являются обработчиками различных типов
// XML-данных и будут вызываться парсером в процессе разбора.// Функция для обработки начальных тегов XML
// На входе:
//   - указатель на SAX парсер
//   - имя XML тега
//   - массив аттрибутовfunction saxStartElement($parser,$name,$attrs)
{
    global $currentNews,$index;
    switch($name)
    {
        case 'newsLine':// Тег newsLine содержит все новости. Мы должны подготовить
// массив $news для приема новостей из XML файла.            $news = array();
            break;
        case 'news':// Каждая новость находится в теге news. Подготавливаем массив
// $currentNews для приема этой новости            $currentNews = array();// Если у новости есть дата - сохраняем ее в массиве            if (in_array('date',array_keys($attrs)))
                $currentNews['date'] = $attrs['date'];
            break;
        default:// Все остальные теги, которые могут встретиться в XML файле
// находятся внутри тега <news>, поэтому мы просто запоминаем
// их название с тем, чтобы знать, какие именно данные мы
// обрабатываем.            $index = $name;
            break;
    };
}// Функция для обработки конечных тегов XML
// На входе:
//   - указатель на SAX парсер
//   - имя XML тегаfunction saxEndElement($parser,$name)
{
    global $news,$currentNews,$index;
    if ((is_array($currentNews)) && ($name=='news'))// Если в данный момент у нас есть массив $currentNews (т.е.
// мы обрабатываем содержимое новости) и имя закрывающего
// тега - "news", то это значит, что данные для этой новости
// кончились и мы можем поместить готовую новость в массив
// новостей.    {
        $news[] = $currentNews;// Уничтожаем массив текущей новости, чтобы показать, что
// в данный момент мы не занимаемся получением данных для
// новости.        $currentNews = null;
    };// В любом случае закрытие тега означает, что символьные
// данные, получаемые парсером не нужно помещать куда-либо.    $index = null;
}// Функция для обработки символьных данных
// На входе:
//   - указатель на SAX парсер
//   - символьные данные XMLfunction saxCharacterData($parser,$data)
{
    global $currentNews,$index;// Мы принимаем только данные для новостей, помещенные в
// какой-нибудь тег. Все остальные символьные данные
// (как правило это пустое пространство, использованное
// для форматирования) мы опускаем за ненадобностью.    if ((is_array($currentNews)) && ($index))
        $currentNews[$index] = $data;
}// Создаем SAX парсер, который будет использоваться для
// обработки XML-данных.$parser = xml_parser_create();// Регистрируем функции для обработки различных типов
// XML-данных:
//  - начальный и конечный тэги XMLxml_set_element_handler($parser,'saxStartElement','saxEndElement');//  - символьные данныеxml_set_character_data_handler($parser,'saxCharacterData');// Также существуют аналогичные функции для регистрации
// обработчиков других типов XML-данных.
// Убираем case folding, в этом случае имена тэгов будут
// передаваться обработчикам в оригинальном виде. Если case
// folding включен, то все имена тегов будут переведены
// в верхний регистр.xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,false);// Получаем содержимое XML-файла с новостями.$xml = join('',file('news.xml'));// Производим парсинг (разбор) полученного XML-файла.
// В процессе разбора парсер будет вызывать описанные нами
// функции и в результате мы получим массив $news,
// содержащий новости из XML-файла.if (!xml_parse($parser,$xml,true))// Парсер возвращает значение FALSE, если произошла
// какая-либо ошибка. В этом случае мы также прекращаем
// выполнение скрипта и возвращаем ошибку.    die(sprintf('Ошибка XML: %s в строке %d',
        xml_error_string(xml_get_error_code($parser)),
        xml_get_current_line_number($parser)));// Уничтожаем парсер, освобождая занятые им ресурсыxml_parser_free($parser);
?>

В результате работы файла test.php мы получим массив $news, содержащий все новости из файла news.xml. Если, к примеру сделать print_r($news), чтобы посмотреть содержимое массива, то мы увидим примерно следующее:

Array
(
    [0] => Array
        (
            [date] => 1.1.2002
            [title] => title 1
            [text] => news text 1
        )
    [1] => Array
        (
            [date] => 5.1.2002
            [title] => title 2
            [text] => news text 2
        )
    [2] => Array
        (
            [date] => 10.1.2002
            [title] => title 3
            [text] => news text 3
        )
)

Для того, чтобы потом вывести новости на странице, нам будет необходимо всего-лишь обработать элементы массива, например так:

<html>
<head>
    <title>Новости</title>
</head>
<body>
<table width="100%" border="1"><?php
foreach($news as $n)
{
?><tr>
    <td width="90%"><b><?php echo $n['title']; ?></b></td>
    <td><?php echo $n['date']; ?></td>
</tr>
<tr>
    <td colspan="2"><?php echo $n['text']; ?><br><br></td>
</tr><?php
};
?></table>
</body>
</html>

Однако, я думаю, вы уже заметили очевидные неудобства этого метода обработки XML-документов. В первую очередь это очевидная сложность в написании обработчиков для различных типов XML-данных. Ведь вам необходимо самостоятельно заботиться о том, чтобы передать другим обработчикам информацию о том, что делать с той или иной информацией, которую они получили. Несложно догадаться, что в случаях более сложной структуры XML документа эти проверки станут еще более сложными и легко могут стать источником ошибок. Кроме того очевидно, что набор обработчиков различен для каждой отдельно взятой струтруры XML-документа и при изменении этой структуры код обработчиков необходимо переписывать.

Все эти недостатки делают область применения SAX достаточно ограниченной, тем более в условиях того, что существует другой, гораздо более мощный и удобный стандарт обработки XML-документов - DOM. О нем и пойдет речь в следующем разделе.


Домен продается

Популярное

Не так давно в сети появился новый сервис, под названием Dead Man Zero. Этот сервис сделал...
Рынок социальных площадок уже давно стал стабильным. Несмотря на то, что время от времени...
Artisteer 4 – единственный в своем роде продукт, позволяющий автоматизировать работу над созданием...
Апрель 2024 (1)
Октябрь 2018 (14)
Февраль 2017 (3)
Январь 2017 (1)
Август 2016 (1)
Май 2016 (2)

Карта сайта: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41

Друзья сайта



Случайная цитата

Боб Хейз:

"Пятнадцать лет назад компании конкурировали друг с другом в цене. Сейчас - это качество. Завтра - это дизайн."

Опрос

Ваша техника?

Настольный компютер
Ноутбук
Смартфон
iPad
iPhone
другое