Работа с XML при помощи скриптового языка PHP

0
5390

xml php

Одним из приложений XML является RSS (Rich Site Summary), в котором отдельные элементы (например, заголовки новостей) представлены как полностью выделенные элементы, позволяющие другим сайтам получать последние новости в таком формате, в каком они желают их получить и отобразить у себя на страницах в полном согласии с правилами XML-обмена данными.
xml php RSS версии 0.91 был разработан компанией Netscape для их сети "My Netscape Network", и он позволяет создать XML- файл, который содержит информацию о сайте, а также отдельные элементы, которые имеют "заголовок", "ссылку" и "описание". Это отлично, но как нам, получив RSS- файл, извлечь из него информацию и опубликовать ее с помощью HTML? phpКаждый язык позволяет делать это по-своему, но здесь мы будем использовать PHP с его встроенным XML- парсером. PHP использует библиотеку expat Джеймса Кларка, которая у вас уже есть, если у вас установлен Apache версии 1.3.9 или старше. Чтобы разбирать документы XML при помощи PHP, нужно включить аргумент --with-xml и собрать PHP из исходников.
xmlМы напишем простой скрипт, который разбирает RSS- файл, извлекает из него информацию, форматирует ее и отображает ее как обычный HTML. Он не только служит примером того, как разбирать XML в PHP, но может быть также включен в любой другой скрипт, чтобы отображать эту информацию.

Первое, что нам следует сделать - это создать класс, который будет хранить наши заголовки:

class xItem {
var $xTitle;
var $xLink;
var $xDescription;
}

Затем нам нужно определить несколько глобальных переменных для основной информации о сайте и массив для хранения объектов заголовка:
$ sTitle = "";
$ sLink = "";
$ sDescription = "";
$ arItems = array();
$ itemCount = 0;

Далее наши первые две функции:
function startElement($ parser, $ name, $attrs) {
global $ curTag;
$ curTag .= "^$ name";
}
function endElement($ parser, $ name) {
global $ curTag;
$caret_pos = strrpos($ curTag,^);
$ curTag = substr($ curTag,0,$caret_pos);
}

Чтобы разобрать XML в PHP, вам следует определить функции, которые вызываются, когда:

  • парсер встречает начальный элемент тега;
  • парсер встречает конечный элемент тега;
  • парсер встречает данные между начальным и конечным тегом.

Мы оформим их следующим образом: установив глобальную переменную ($ curTag) как строку, содержащую все родительские теги, разделенные знаком ^. Например, для такой XML-структуры:

переменная $ curTag будет выглядеть так:
^ RSS^CHANNEL^ITEM

Все, что нам нужно сделать - это обнаружить, когда парсер встретит правильную $ curTag, и в соответствии с ним извлечь данные. Все это производится в функции characterData. Вот она:
function characterData($ parser, $data) {
global $ curTag; // сначала информация о канале
global $ sTitle, $ sLink, $ sDescription;
$titleKey = "^ RSS^CHANNEL^TITLE";
$linkKey = "^ RSS^CHANNEL^LINK";
$descKey = "^ RSS^CHANNEL^DESCRIPTION";
if ($ curTag == $titleKey) {
$ sTitle = $data;
} elseif ($ curTag == $linkKey) {
$ sLink = $data;
} elseif ($ curTag == $descKey) {
$ sDescription = $data;
}
// теперь получаем элементы
global $ arItems, $ itemCount;
$itemTitleKey = "^ RSS^CHANNEL^ITEM^TITLE";
$itemLinkKey = "^ RSS^CHANNEL^ITEM^LINK";
$itemDescKey = "^ RSS^CHANNEL^ITEM^DESCRIPTION";
if ($ curTag == $itemTitleKey) {
// создаем новый xItem
$ arItems[$ itemCount] = new xItem();
// устанавливаем свойства нового элемента
$ arItems[$ itemCount]->xTitle = $data;
} elseif ($ curTag == $itemLinkKey) {
$ arItems[$ itemCount]->xLink = $data;
} elseif ($ curTag == $itemDescKey) {
$ arItems[$ itemCount]->xDescription = $data;
// увеличиваем счетчик
$ itemCount++;
}
}

xml htmlЭта функция проверяет, содержит ли $ curTag нужную нам строку, и если это так, извлекает из нее данные и присваивает переменным. Сначала она извлекает основную информацию о сайте, затем проверяет, есть ли элементы . Если есть, она создает xItem, вставляет его в массив $ arItems и устанавливает свойства для соответствующих данных в RSS- файле.

Теперь, когда функции определены, мы воспользуемся стандартным в PHP способом для связи с XML- парсером:
// основной цикл
$xml_ parser = xml_ parser_create();
xml_set_element_handler($xml_ parser, "startElement", "endElement");
xml_set_character_data_handler($xml_ parser, " characterData");
if (!($fp = fopen($uFile,"r"))) {
die ("Не могу получить RSS");
}
while ($data = fread($fp, 4096)) {
if (!xml_parse($xml_ parser, $data, feof($fp))) {
die(sprintf("XML ошибка: %s на строке %d", xml_error_string(xml_get_error_code($xml_ parser)), xml_get_current_line_number($xml_ parser)));
}
}
xml_ parser_free($xml_ parser);

Все, что в вышеприведенном коде начинается с "xml_" - это стандартные XML- функции PHP. Мы сообщаем парсеру, что наши функции должны выполняться, когда он встречает начальный тег, конечный или - данные, а затем мы загружаем RSS файл (переменная $uFile должна быть установлена на нужный RSS- Файл) и запускаем парсер (xml_parse).

Теперь, когда наши данные разобраны по отдельным переменным, не так трудно перевести их в HTML:

xml phpМы добавили несколько переменных для описания, шрифта, его размера.
Когда дело касается обмена данными, XML трудно что-либо противопоставить. Определение XML-формата, который может быть использован многими людьми (как RSS) - это только одна из выгод этой сложной, но элегантной технологии.

Полный исходник смотрите здесь:
class xItem {
var $xTitle;
var $xLink;
var $xDescription;
}

// general vars
$ sTitle = "";
$ sLink = "";
$ sDescription = "";
$ arItems = array();
$ itemCount = 0;

// ********* Start User-Defined Vars ************
// rss url goes here
$uFile = "http://www.wirelessdevnet.com/wirelessnews/ rss/dailynews. rss";
// descriptions (true or false) goes here
$bDesc = true;
// font goes here
$uFont = "Verdana, Arial, Helvetica, sans-serif";
$uFontSize = "2";
// ********* End User-Defined Vars **************

function startElement($ parser, $ name, $attrs) {
global $ curTag;

$ curTag .= "^$ name";

}

function endElement($ parser, $ name) {
global $ curTag;

$caret_pos = strrpos($ curTag,^);

$ curTag = substr($ curTag,0,$caret_pos);

}

function characterData($ parser, $data) { global $ curTag; // get the Channel information first
global $ sTitle, $ sLink, $ sDescription;
$titleKey = "^ RSS^CHANNEL^TITLE";
$linkKey = "^ RSS^CHANNEL^LINK";
$descKey = "^ RSS^CHANNEL^DESCRIPTION";
if ($ curTag == $titleKey) {
$ sTitle = $data;
}
elseif ($ curTag == $linkKey) {
$ sLink = $data;
}
elseif ($ curTag == $descKey) {
$ sDescription = $data;
}

// now get the items
global $ arItems, $ itemCount;
$itemTitleKey = "^ RSS^CHANNEL^ITEM^TITLE";
$itemLinkKey = "^ RSS^CHANNEL^ITEM^LINK";
$itemDescKey = "^ RSS^CHANNEL^ITEM^DESCRIPTION";

if ($ curTag == $itemTitleKey) {
// make new xItem
$ arItems[$ itemCount] = new xItem();

// set new item objects properties
$ arItems[$ itemCount]->xTitle = $data;
}
elseif ($ curTag == $itemLinkKey) {
$ arItems[$ itemCount]->xLink = $data;
}
elseif ($ curTag == $itemDescKey) {
$ arItems[$ itemCount]->xDescription = $data;
// increment item counter
$ itemCount++;
}
}

// main loop
$xml_ parser = xml_ parser_create();
xml_set_element_handler($xml_ parser, "startElement", "endElement");
xml_set_character_data_handler($xml_ parser, " characterData");
if (!($fp = fopen($uFile,"r"))) {
die ("could not open RSS for input");
}
while ($data = fread($fp, 4096)) {
if (!xml_parse($xml_ parser, $data, feof($fp))) {
die(sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($xml_ parser)), xml_get_current_line_number($xml_ parser)));
}
}
xml_ parser_free($xml_ parser);

// write out the items
?>

for ($i=0;$i $t xItem = $ arItems[$i];
?>
xTitle); ?>

if ($bDesc) {
?>
xDescription); ?>

}
echo ("
");
}

Автор: Мир переводов
ОЦЕНИТЬ НОВОСТЬ
5 (голосов: 204)

Комментарии:

ВВЕРХ