Как сделать новостную ленту, используя XML/XSLT

Интсрукция по созданию новостной ленты с использованием современных технологий

[Max (max_kma@mail.ru)]

XML/XSLT - как сделать новостную ленту без PHP и SQL

Приручение XML

Иллюстрация поиска решения + как возможно проще про XML (навеяно сайтом gentoo.org и проектом linuxdoc, где XML технологии давно и успешно применяются)
(( изучение материалов http://www.w3c.org крайне приветсвуется ))
(( см.также http://www.xmlsoft.org/XSLT.html ))

Задача, в общем, типичная: "сделать страницу с новостями"

Более подробно :

  • надо иногда публиковать небольшие сообщения.
  • механизм публикаций сугубо на моей совести.
  • из всего офисного барахла под это дело подходит только шлюз, на котором крутится Linux.
  • на шлюзе отсутсвуют (пока) apache,php,sql
Первое-же решение (в лоб) :
  • установить apache,php,sql
  • создать БД и php-шный скрипт
Это решение после перекура и бутылки пива отброшено, как заведомо неверное, потому как придется холить и лелеять помимо apache еще и php с sql. И вообще ставить sql только ради новостей - как-то глупо. Сделать руками html и потом всегда его править - тоже как-то не то..

После чего последовало изучение - что уже есть из того, что может пригодиться. Ага ! xsltproc имеется..man xsltproc..Хмурю лоб - вещь хорошая, но придется расширять кругозор - понять как xslt работает..

links http://www.w3c.org - через пару часов ясно, что для поставленной задачи вполне подходит, и минимальный знаний подчерпнутых из стандарта хватит для решения.

Второе решение :

  • установить только apache (куда-ж без него-то)
  • сделать xml-страницу и к ней xslt
  • для публикации редактировать xml-ку и натравливать xsltproc, чтобы получить html
Сказано-сделано :
  • ставлю apache
  • пишу news.xml,news.xsl # xstproc news.xsl news.xml > news.html
  • проверяю - работает
Ура ! html не надо править в ручную, достаточно внести нужные правки в xml (что проще) и все ok. Однако нет предела совершенству - возникает следующий вопрос - а вот например сделать файл news2.xml как дополнение к news.xml?

Создаю..

# cp news.xml news2.xml
Пробую..
# xsltproc news.xsl news.xml news2.xsl    
Не получилось: html-заголовки повторены дважды.. А может, их сначала слить ?
# cat news.xml news2.xml | xsltproc news.xsl -
тоже не то.. в xml-е корневая запись должна быть одна (да и заголовок тоже один) Ну тогда sed`ом их.

Алгоритм примерно таков : для суммарного файла сделать свой заголовок и свой хвост, и слить в него все исходные, попутно вырезая строчки типа <?xml...?> Делаю..вышло..только придется xsl немного править

Окончательное решение : каждую новость помещать в отдельный xml..(в каталог news-in) при добавлении/удалении новости переделывать суммарный xml и транслировать его в html. чтобы новости шли последовательно исходные файлы сортировать по времени. а старые новости (;-)) можно убивать по крону.. Вуалля !

Плюсы решения :

  • полученны и примененны новые знания
  • сэкономлено время
  • сэкономленны ресурсы (один раз запустить xslt вместо того чтоб круглосуточно гонять базу)
  • оформление(дизайн) отделен от содержания - внешний вид можно курочить отдельно от логики
  • внешние приложения могут обращаться напрямую к summary.xml и брать оттуда информацию (проще чем царапать из html)
Минусы :
  • чтобы создать/опубликовать новость надо все-же знать xml и принятый формат
  • надо еще иметь права на запись в news-in..(хотя новости можно собирать и по домашним каталогам)

Кратко про XML :

(в рамках приведенного примера)

Файл начинается с заголовка <?xml version="version" encoding="encoding"?> далее - иерархия узлов,обрамленных тегами как в html - <tag>текст</tag> в xml-файле должен быть только один узел верхнего уровня. теги могут иметь аттрибуты оформленные в виде attr="value" Например : <person sex="man">Петя</person>

Кратко про XSL :

(в рамках приведенного примера)

xsl соответсвует формату xml, то есть тоже начинается с заголовка и включает иерархию узлов. Верхний уровень будет зваться <xsl:stylesheet> Есть три важных узла : <xsl:template macth="xpath"> - описание шаблона,который будет применяться к узлам xpath <xsl:apply-templates select="xpath"/> - ставиться в то место где надо применить шаблон (куда будет подставлен результат) <xsl:value-of select="xpath"/> - похож на apply-templates, но шаблон применяться не будет, а будет подставлена значение xpath xpath адресует узлы в исходном xml-документе "/" - корневой узел "node" - узел типа node следующий за данным "@attr" - значение аттрибута attr текущего узла и так далее..

Прим.:

  1. Mozilla и IE вполне спокойно открывают xml`ки и делают все требуемые xslt-преобразовая уже на стороне клиента.(без xsltproc)
  2. Никто не запрещает прицепить еще и CSS
  3. "Не стреляйте в пианиста - он играет как умеет" :-) - слияние xml-ков можно (и нужно наверное) делать не sed`ом, а тем-же xslt к примеру. (правда sed`ом проще и быстрее) - в вызове sed - есть видимо мелкая ошибочка ;-)
  4. Не забудьте правильно выставить права доступа !!
Далее приведу все упомянутые файлы :
  • news.sh - элементарный bash-скрипт, делает из нескольких файлов .xml один
  • summary.xsl - шаблон трансформации нашего файла с новостями в html
  • sample-news.xml - пример файла новостей
  • summary.css - таблица стилей
---- news.sh ----------------------------------------------------
#!/bin/bash
# делаем заголовок для суммарного xml-файла
echo '<?xml version="1.0" encoding="koi8-r"?>' > summary.xml
echo '<?xml-stylesheet type="text/xml" href="summary.xsl"?>'>> summary.xml
echo '<summary>' >> summary.xml
# сливаем в него все имеющиеся новости
for name in `ls -1 --sort=time ./news-in/*.xml | head -n 30`;do
    sed "s/<?xml.*?>/<!--removed-->/" $name >> summary.xml
done
# пишем хвост для суммарного файла
echo '</summary>'>> summary.xml
# делаем html
xsltproc summary.xsl summary.xml > summary.html
---- end news.sh ------------------------------------------------

---- summary.xsl ------------------------------------------------

<?xml version="1.0" encoding="koi8-r"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="koi8-r"/>
<!-- предыдущие строки можно считать просто заклинанием -->
<!-- генерация html-заголовка (обработка корневой записи) -->
<xsl:template match="/">
    <html lang="ru">
    <head>
    <!-- не ставьте Content-Type - xsltproc сам его сделает -->
    <title>Новости</title>
    <!-- а вот так цепляется таблица стилей -->
    <link rel="stylesheet" type="text/css" href="summary.css"/>
    </head>
    <body>
    <!-- обработка всех новостей -->
    <xsl:apply-templates select="summary"/>
    </body>
    </html>
</xsl:template>

<!-- перехватываем узлы summary - он у нас только один такой -->
<xsl:template match="summary">
    <h3>Новости</h3>
    <!-- обработка каждой новости -->
    <xsl:apply-templates select="news"/>
</xsl:template>

<!-- перехватываем узлы news - описания каждой отдельной новости -->
<xsl:template match="news">
    <!-- форматирование новости -->
    <span id="news-date"><xsl:value-of select="date"/></span>
    <span id="news-author"><xsl:value-of select="author"/></span>
    <span id="news-title"><xsl:value-of select="title"/></span>
    <span id="news-brief"><xsl:value-of select="brief"/></span>
    <p>
    <xsl:apply-templates select="text()"/>
    </p>
    <hr/>
</xsl:template>

</xsl:stylesheet>
---- end summary.xsl ----------------------------------------------

---- sample-news.xml -----------------------------------------------

<?xml version="1.0" encoding="koi8-r">
<!-- Просто пример формата файла с новостью -->
<news>
    <date>14.01.2004</date>
    <author>I`m</author>
    <title>Пример новости</title>
    <brief>файл сделанный для примеров и тестов</brief>
    Дальше пошел порсто произвольный текст..
    И так далее и так далее..
</news>
---- end sample-news.xml -------------------------------------------

---- summary.css ---------------------------------------------------

#news {
    border-width:2px;
    border-style:outset;
}
#news-date {
    font-style:italic;
    margin-left:10px;
}
#news-author {
    font-style:italic;
    font-size=80%;
    margin-left:10px;
}
#news-title {
    font-weight:bold;
    margin-left:10px;
    text-transform:uppercase;
}
#news-brief {
    margin-left:10px;
}
--- end summary.css ---------------------------------------------------

Статья взята с сайта OpenNet.

[ опубликовано 30/01/2004 ]

Max (max_kma@mail.ru) - Как сделать новостную ленту, используя XML/XSLT   Версия для печати