2003-01-21 16:55:15 UTC
В связи с появлением в парсере возможности работать с внешними файлами (не на локальном сервере), появилась возможность получать и выводить информацию из внешних источников у себя на сайте.
В этом примере я рассмотрю использование внешнего XML файла с анонсами материалов, для опубликования ссылок на эти материалы у себя на сайте. Сделаю это на примере сайта php в деталях. Содержимое и структуру XML этого файла смотрите по адресу, который найдете в нижеприведённом коде.
Небольшое предостережение — если XML файл расположен на сервере с русским Apache, нужно обязательно отключить перекодировку с его помощью, иначе может возникнуть ситуация с несовпадением реальной и кодировки в XML декларации. Ну и теперь к делу, — код выглядит следующим образом:
####### # формирование анонсов последних материалов # с сайта php в деталях # Блок <ul>...</ul> написал Константин Томашевич (konst@design.ru) @phpdetails[][src;local_file;xml;list;now] # определяем локальный файл где находится XML $local_file[/phpdetails/last10.xml] # проверяем локальный файл, - если его дата изменения более чем на # день старее текущего времени, грузим его с внешнего сервера $src[^file::stat[$local_file]] $now[^date::now[]] ^if($src.mdate < $now-1){ # пытаемся загрузить внешний XML файл и сохранить его # если не удается загрузка, обрабатываем исключение и ничего не делаем ^try{ $src[^file::load[text;http://detail.phpclub.net/last10.xml]] ^src.save[text;$local_file] }{ $exception.handled(1) } } # всегда создаем объект класса xdoc из XML файла на локальном диске # разумеется он должен всегда существовать. При удачной загрузке с # внешнего сервера, он ещё и постоянно обновляется $xml[^xdoc::load[$local_file]] # хэш элементов(анонсов) из файла, нужен для определения количества анонсов $list[^xml.select[/last/item]] <ul> #!*!# нумерациЯ с 0 (исправлен range в if) ^for[i](0;$list-1){ #!*!# нет смысла делать еще раз selectXXX, ибо мы уже в цикле типа xsl:for-each #!*!# более того, если не проверЯешь наличие аттрибутов, можно сократить до #!*!# одной строки - $list == hash of xnode (/last/item) <li> ^list.[$i].getAttribute[date] <a href="http://detail.phpclub.net/^list.[$i].getAttribute[dir]^list.[$i].getAttribute[file].htm"> ^list.[$i].getAttribute[title] </a> </li> } </ul>
Немного комментариев.
- Работа по вытягиванию информации из XML всегда ведется с локальным файлом.
- Раз в сутки проверяется дата изменения локального файла и если она более чем на сутки старее текущий производится загрузка внешнего файла.
- Здесь сделано предположение, что, внешний файл меняется раз в сутки, если это не так и файл меняется гораздо реже, стоит этот период увеличить.
Пусть вас не удивляют странные комментарии сделанные между тегами ul
— первоначальный вариант кода был такой:
<ul> ^for[i](1;$list){ $date{^xml.selectString[string(/last/item[position() = $i]/@date)]} $title{^xml.selectString[string(/last/item[position() = $i]/@title)]} $path{^xml.selectString[string(/last/item[position() = $i]/@dir)]} $file{^xml.selectString[string(/last/item[position() = $i]/@file)]} <li>$date <a href="http://detail.phpclub.net/${path}${file}.htm">$title</a></li> } </ul>
Да, — совсем не обязательно проверять дату изменения, можно проверять и дату создания, но это не принципиально.
И в заключении — большое спасибо Константину Томашевичу, за ценные советы по работе с методами класса xnode
и написанию части кода примера.