Ключевые слова:xml, web, (найти похожие документы)
From: Max <max_kma@mail.ru>
Newsgroups: email
Date: Mon, 14 Jan 2004 14:31:37 +0000 (UTC)
Subject: Как сделать новостную ленту испльзуя XML/XSLT
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-шный скрипт
Это решение после перекура и бутылки пива отброшено, как заведомо неверное,
потому как придется холить и лелеять помимо апача еще и пхп с 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 ---------------------------------------------------
можно сделать интереснее:
иметь один фаил контейнер для новостей который содержит ссылки на фаилы новостей
при конвертации в html ползовать команду с префиксом --xinclude
$ xsltproc --xinclude form.xsl document.xml > result.html
в результате мы получаем настоящую модульность
для xml документов
теперь для обновления нужно просто переименовать
файлы новостей (mv 9.xml 10.xml)
здесь имеется в виду чем больше номер тем старше новость
$ ./script.sh
Примеры Файлов:
document.xml - контейнер для новостей
1.xml- одн из фаилов с объектом новость
script.sh скрипт для переименования новостей(update)
------------- begin document.xml------------------
<?xml version="1.0" encoding="koi8-r"?>
<document xmlns:xi="http://www.w3.org/2003/XInclude"> <news-section>
<!-- ссылки на отдельные фаилы -->
<xi:include href='news/1.xml' parse='xml'/>
<xi:include href='news/2.xml' parse='xml'/>
<!-- и так далее -->
</news-section>
</document>
------------- end document.xml------------------
простая новость
------------- begin 1.xml----------------
<news>
<date>14.01.2004</date>
<author>I'm</author>
<title>Пример новости</title>
<brief>файл сделанный для примеров и тестов</brief>
Дальше пошел порсто произвольный текст..
И так далее и так далее..
</news>
------------- end 1.xml------------------
-------------- begin script.sh----------------
#!/bin/sh
for name in 10 9 8 7 6 5 4 3 2 1
do
mv $name.xml $old_name.xml
old_name=$name
done
-------------- end script.sh----------------