В сети доступно
масса документации по языку XSL. Данный раздел не претендует на роль документации по языку, а лишь кратко, по шагам объясняет, как создать свой XSLT-шаблон.
Описанная ниже схема успешно мною используется уже более 3 лет. По началу я к
XSLT относился с большой опаской (особенно, когда разбирал чужие исходники), однако однажды поняв, что к чему, уже не представляю, как без него можно работать.
Рабочий стол
Определим, что нам нужно для работы:
- Входной XML-документ
- XHTML-макет шаблона
- Парсер XML для склейки XML с XSL
У меня входной
XML документ выдает CMS-система, в которой каждая страница с материалом собирается в
XML-дерево.
К
XHTML-макету никаких ограничений нет. Есть лишь определенные рекомендации по верстке, которые позволят значительно сэкономить время на формирование шаблона.
В качестве парсера (сборщика) конечного документа можно использовать браузер. Нужно лишь указать в
XML-документы путь к файлу шаблону:
<?xml-stylesheet type="text/xsl" href="template.xsl" ?>
Хотя, как показала практика, этот механизм довольно глючный (мне пришлось пользовать
IE). Лучше воспользоваться средствами
XML-парсинга языка, на котором написана CMS-система. Я использую
Parser (на нем, вообщем-то, у меня вся система и работает).
Входной XML-документ
Для начала разберемся со входным
XML-документом. Для того, чтобы использовать
XSL нужно иметь полное представление о его структуре.
Я использую следующую схему:
<?xml version="1.0" encoding="windows-1251"?>
Начало
<lang_table>
/>
</lang_table>
<item id="0" parent_id="0" is_published="1" section="1">
Начало
/
<item id="1" parent_id="0" is_published="1" section="1">
Новости
news
Обозначенный выше пример схемы не претендует на свою оптимальность. В силу тех или иных причин, мне он удобен. Но, обо всем по порядку.
<?xml version="1.0" encoding="windows-1251"?> — заголовок
XML-файла. Должен идти строго с начала файла. В нем прописана версия используемого XML-языка и кодировка документа. Я как правило работаю в
windows-1251 (пока так удобнее), но, по идее
UTF-8 лучше.
- корневой элемент документа (можно придумать свое имя). Атрибуты:
- Lang - язык документа. Нужен для создания мультиязычных шаблонов.
- Id - идентификатор текущего раздела.
<lang_table> - таблица языков, используемых на сайте.
- блок элементов навигации:
- блок основной навигации (основная структура сайта):
<item id="0" parent_id="0" is_published="1" section="1"> - элемент структуры сайта. Атрибуты:
- Id - идентификатор раздела.
- Parent_id - идентификатор родительского раздела.
- Is_published - опубликован ли раздел.
- Dir - uri-адрес раздела. По нему формируются полные адреса.
- Section - тип раздела. Используется если необходимо разбить меню на основное и сервисное.
- блок содержимого.
В моей CMS используется модульная структура: все наполнение сайта представляет собой модули двух видов:
- Html - текстовый модуль. Статические модули, которые заполняет редактор сайта.
- Com - модуль-компонента. Динамические модули, которые формируют различные программные модули CMS: новости, статистика, поисковые блоки и т.д.
В XSL-шаблонах есть разметка блоков, в которые можно размещать модули. Для определения блоков я использую простую нумерацию.
CMS при сборке страницы просто выводит в все модули, которые задействованы на странице в виде:
Атрибуты:
- Id - идентификатор модуля.
Container - блок-назначение (в каком блоке шаблона выводиться).
Sorting - порядок вывода в блоке.
Type - тип:
- Com - модуль-компонентаю
Html - текстовый модуль.
Method - обработчик данных.
Title - название модуля.
DTD я практически не использую (лишь в самом общем виде):
<!DOCTYPE site_page [
<!ENTITY nbsp " ">
<!ENTITY sect "§" >
<!ENTITY copy "©">
<!ENTITY laquo "«">
<!ENTITY reg "®">
<!ENTITY deg "°">
<!ENTITY plusmn "±">
<!ENTITY para "¶">
<!ENTITY raquo "»">
<!ENTITY times "×">
<!ENTITY bull "•">
<!ENTITY hellip "…">
<!ENTITY ndash "–">
<!ENTITY mdash "—">
<!ENTITY lsquo "‘">
<!ENTITY rsquo "’">
<!ENTITY sbquo "‚">
<!ENTITY ldquo "“">
<!ENTITY rdquo "”">
<!ENTITY bdquo "„">
<!ENTITY lsaquo "‹">
<!ENTITY rsaquo "›" >
<!ENTITY euro "€">
]>
Его можно вставить прямо в XML-документ. Сразу после <?xml version="1.0" encoding="windows-1251"?>.
Подготовка XHML-шаблона
XSL-шаблон создается на базе XHTML-шаблона (некой типовой страницы сайта). Код XHTML-страницы, при этом, должен быть валидным.
Рассмотрим по шагам процесс создания шаблона.
Проверив валидность XHML-страницы своего шаблона, для облегчения собственной работы, обозначьте в нем положение всех динамических блоков:
- Меню (и других элементов навигации).
- Информационных блоков страницы - то место в шаблоне, в котором будут выводиться модули сайта.
- Заголовка/названия страницы.
Сделать это лучше всего с помощью обычных HTML-комментариев:
...
Администрирование сайта
...
...
Всякие новости
...
Текст
...
Основы описания XSL-шаблонов
Все файлы XSL-шаблонов имеют следующий вид:
<xsl:stylesheet version = '1.0' encoding="UTF-8"?>
<xsl:template match="element">
данные шаблона
</xsl:template>
</xsl:stylesheet>
Где: <xsl:stylesheet version = '1.0' encoding="UTF-8"?> - определяет тип XML-документа и кодировку. Я использую UTF-8 (не спрашивайте, почему).
<xsl:stylesheet> </xsl:stylesheet> - начало и конец XSL-документа.
<xsl:template match="element"> </xsl:template> - начало и конец шаблона для элемента element.
Шаблоны можно условно разделить на три вида:
<xsl:template match="element"></xsl:template> - шаблон, описывающий правила преобразования элемента element. Применяется автоматически ко всем элементам element.
<xsl:template match="element" mode="mode1"></xsl:template> - шаблон, описывающий правила преобразования элемента element в режиме mode1. Таким образом можно описать различные правила обработки элементов element.
<xsl:template name="template-name"></xsl:template> - шаблон с именем template-name. Не имеет привязки к какому-либо элементу XML-документа.
Если элементы одного вида могут встречаться в различных частях структуры XML-документа (например, в XML-документе, формируемом системой элемент item используется повсеместно и имеет разное значение), то в шаблоне можно указать "структурный адрес" такого элемента:
<xsl:template match="navigation/sections/item"></xsl:template>
При этом, порядок применения шаблонов иерархичный, т.е., сначала шаблон применяется к корневому элементу, а затем, к дочерним, т.е. если мы вызвали обработчик для navigation, то для вызова обработчика для navigation/sections/item нам достаточно указать адрес sections/item.
Структура папок шаблонов
Для того, чтобы хранить на одном сайте несколько модулей необходимо как-то продумать структуру их хранения в папкам. При этом, удобнее разбить шаблоны на модули по нескольким xsl-файлам. Такой подход позволит в дальнейшем повторно их использовать при создании новых шаблонов.
В простейшем варианте можно создать каталог xsl и там все складировать.
Далее, чтобы внутри этого каталог шаблоны не путались (для каждого шаблона у нас получиться несколько файлов) создадим вложенные каталоги:
- template_folder - каталог с файлами шаблона. Называть ее можно по имени шаблона, например my_template.
- dtd - файлы описания основных сущностей. Могут быть полезными.
- lang - шаблоны сообщений для различных языков (если на сайте используется их используется несколько).
- mod - шаблоны модулей.
Нам для начала потребуется создать каталог xsl/my_template и в нем, файл layout.xsl следующего вида:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet SYSTEM "../dtd/entities.dtd">
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/node()">
</xsl:template>
</xsl:stylesheet>
Где:
<xsl:template match="/node()"> </xsl:template> - шаблон для элемента /node() (корневого). Вместо /node() можно указать //document, т.к. он у нас являеться корневым узлом.
Копируем весь XHTML-код внутрь блока <xsl:template match="/node()"></xsl:template>
Этот шаблон будет автоматически применяться ко всему XML-документу. В нашем случае, XSL-преобразование заменит весь XML-код на XHTML-код вашего шаблона.
Далее, необходимо в директории XSL создать файл template.xsl (где, template - название вашего шаблона), в котором размещаем следующий код:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href=" my_template /layout.xsl"/>
</xsl:stylesheet>
Где:
<xsl:import href="my_template/layout.xsl"/>
Директива импорта внешнего XSL-файла (обрабатываеться XSL-процессором) из указанного файла. Путь к файлу указываем относительный.
Создание шаблона для основного навигационного меню
Наш предыдущий шаблон не обладает никакой динамикой, т.к. просто заменяет весь выходной XML-документ на код нашего шаблона.
Следующий шаг - создание шаблона для меню.
Меню навигации сайта строиться на основе его структуры, представленной в XML-документе в следующем виде:
<item id="0" parent_id="0" is_published="1" section="1">
Начало
/
<item id="1" parent_id="0" is_published="1" section="1" hit="yes">
Новости
news
Текущий раздел определяется по двум параметрам:
- Атрибуту id у корневого элемента document - он всегда равен id текущего раздела.
- Атрибуту hit у элемента item - если таковой имеется, то это значит, мы находимся на "главной странице раздела".
Соответственно, для того, чтобы вывести меню сайта необходимо создать шаблон для элементов:
- sections - корневой элемент меню.
- item - элемент меню.
При этом, необходимо учесть, что элементы item могут содержать другие элементы item, в том случае, если у раздела есть подразделы:
1. Создаем в директории xsl/my_template файл navigation.xsl следующего вида:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet SYSTEM "../dtd/entities.dtd">
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="sections" mode="global_menu">
</xsl:template>
</xsl:stylesheet>
2. Вставляем в шаблон код нашего меню из файла layout.xsl:
<xsl:template match="sections" mode="global_menu">
</xsl:template>
3. …а на его место в файле layout.xsl вставляем вызов нашего шаблона меню:
<xsl:apply-templates select="navigation/sections" mode="global_menu"/>
Где:
select="navigation/sections" - относительный (относительно текущего) путь-адрес элемента. При этом, будут обработаны все элементы navigation/sections.
mode="global_menu" - используем шаблон с режимом global_menu. Это нам нужно на тот случай, если нужно будет выводить еще и сервисное меню, отдельно, или "хлебные крошки", или что-еще другое на основе одной и той же ветки навигации.
4. Плюс, добавим в файл layout.xsl директиву импорта файла шаблона navigation.xsl:
<xsl:import href="navigation.xsl"/>
5. Далее, создаем в файле navigation.xsl еще один шаблон, для обработки пунктов меню:
<xsl:template match="item" mode="global_menu">
<xsl:call-template name="href_attribute"/>
<xsl:value-of select="title"/>
</xsl:template>
Где:
<xsl:call-template name="href_attribute"/> - вызов шаблона по имени. При этом шаблон не имеет привязки к элементу, т.е. вызывается произвольно.
<xsl:value-of select="title"/> - вставка-вывод значения элемента title текущего элемента. Если в параметре перед именем элемента поставить символ @ - выводиться будет значения атрибута текущего элемента.
6. Немного изменяем шаблон sections:
<xsl:template match="sections" mode="global_menu">
</xsl:template>
Где:
<xsl:apply-templates select="item" mode="global_menu"/> - обработка всех элементов item элемента sections. При этом, элементы item самих элементов item (sections/item/item) обрабатываться не будут, т.е. выводиться только один уровень меню разделов.
Мы вынесли обработку элементов item (пунктов меню) в отдельный шаблон. При этом, в нем мы добавили еще и вызов другого шаблона: <xsl:call-template name="href_attribute"/>
Этот шаблон будет формировать нормальные uri-ссылки для элементов нашего меню. О нем немного позже.
7. Теперь нам необходимо доделать меню,
чтобы оно учитывало, какой раздел является текущим. Для этого нам придется добавить условную обработку в наш шаблон элемента item:
<xsl:template match="item" mode="global_menu">
<xsl:choose>
<xsl:when test="descendant-or-self::*/@id = /node()/@id">
<xsl:value-of select="title"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="href_attribute"/>
<xsl:value-of select="title"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Здесь мы сталкиваемся с новой конструкцией:
<xsl:choose>
<xsl:when></xsl:when>
<xsl:otherwise></xsl:otherwise>
</xsl:choose>
…которая, собственно, и задает условную обработку XML-элементов. В качестве параметра мы задаем условие: <xsl:when test="descendant-or-self::*/@id = /node()/@id">
В нашем случае это условие равенства атрибутов ID у корневого элемента (document) и текущего элемента (item), которое и определяет, является ли элемент текущим.
Внутри блока <xsl:when></xsl:when> располагается то, что выводиться в случае выполнения условия. В блоке <xsl:otherwise></xsl:otherwise> - если условие не выполняется.
8. Теперь, разберем шаблон href_attribute:
<xsl:template name="href_attribute">
<xsl:attribute name="href">
<xsl:text>/</xsl:text>
<xsl:for-each select="ancestor-or-self::item">
<xsl:value-of select="dir"/>
<xsl:text>/</xsl:text>
</xsl:for-each>
</xsl:attribute>
</xsl:template>
Здесь мы сталкиваемся с инструкцией xsl:attribute. Она позволяет создавать атрибуты для элементов внутри которого она вызывается. В нашем случае мы вызываем ее из элемента a, соответственно, она создаст для него атрибут href, т.е. адрес.
Инструкция <xsl:for-each select="ancestor-or-self::item"> задает цикл обработки для всех элементов, удовлетворяющих условию. В нашем случае мы выбираем ancestor-or-self::item - ось элементов от корневого элемента до текущего по цепочке. В нашем случае это позволяет выбрать для всей цепочки узлы dir, т.е. построить полный адрес текущего узла-раздела.
Далее, нам необходимо каким-то образом определить, как у нас будут обрабатываться модули содержимого. Но, об этом в следующий раз.
UPD:
Материалы к статье. Собрал из того, что было:
parser.proc.ru/iso/xslt-1.zip
В шаблоне все пути прописаны от корня (делал на основе шаблона работающего на реальном сайте) поэтому либо перепишите их на относительные либо запускайте из под Apache.
В архиве входной XML-документ лежит в /xsl/document.xml
комментарии (100)
Мне во многих проектах доводилось плотно заниматься xsl-трансформацией. За это время накопились несколько замечаний, которые стоит учесть при выборе этой технологии.
1. тормозит
Нельзя сказать, что безумно, но если дело доходит до оптимизации скорости ответа сервера — xsl-трансформация окажется одним из самых «узких» мест. Можно писать «правильные» шаблоны и со временем научиться «разгонять» скорость их обработки. Но значительного прироста в скорости это не принесет. В последнем проекте это сыграло решающую роль и пришлось отказаться от xsl вообще.
2. нет четкой структуры. В случае большого объема кода приходится изобретать и постоянно придерживаться четких правил для вложенности шаблонов. Встроенных средств для этого нет.
3. верстальщики не знают xsl. Это заметно осложняет последующую поддержку проекта.
2. Четких правил придерживаться стоит всегда.
3. Плохие верстальщики не хотят знать XSL. Хороших можно научить.
1. действительно это один из способов «разгона», но если страница на 100% динамическая — помогает мало.
2. это гораздо удобней делать, когда правила встроены в технологию или даже диктуются на уровне синтаксиса.
3. к сожалению кадровой политикой везде занимались другие люди и большого выбора верстальщиков не было.
Да вобщем-то верстальщиков тоже можно понять — они шли верстать макеты в хтмл, ну максимум править шаблоны очень похожие на хтмл, а сложный хсл шаблон достаточно далек от результирующего хтмл'я.
И кстати, «я за наших!» т.е. мне нравится xsl и интересно было с ним работать. Но есть моменты на которые необходимо обратить внимание при выборе технологии. Т.к. отказаться от xsl, когда проект уже практически готов будет очень сложно.
А в плане технологий - все просто и неоднократно оговорено. Технологию надо выбирать в зависимости от нужд проекта, а не в зависимости от самой технологии. Это как "php-программист" )
человек имеет право решать - нужно ему это или нет.
знания xsl скорее нужны девелоперу, и как результат, грамотного верстальщика может просто не оказаться под рукой когда он нужен ( девелоперы обычно заняты на 120%)
Во-вторых вы видимо не имели дело с XSLT. Никто при разработке больших проектов не будет верстать все в статике, а затем просить "девелопера" переводить все на XSLT-шаблоны. Это бессмысленая трата времени.
XSLT имеет самое прямое отношение к верстке и является частью Front-End'a.
Кроме того, я ни за кого ничего не решаю, каждый сам себе Прокруст. И вы, пожалуйста не решайте, что мне говорить, а чего не стоит.
Мне кажется это разного плана задачи - одно дело отладить сверстанный дизайн под все браузеры, другое дело связать с бекэндом.
Далее, "не будет верстать все в статике, а затем просить "девелопера" переводить все на XSLT-шаблоны".
Простите, а Вы стадию прототипирования начисто игнорируете? И frontend и backend "по-живому" делаете? Не хочу в это верить, боюсь я таких людей :)
Ну и по последнему - я не указываю Вам, тут все выражают мнение. Обратите внимание, я как раз и писал о том что каждый выбирает сам. Это Вы пытаетесь указать "Плох тот верстальщик, который не хочет научиться большему", что как я вижу есть принуждение.
P.S. XSLT нужно применять осторожно и с умом. И только когда это оправдано.
Backend'ом я не занимаюсь, а frontend сразу начинаю с XSLT, это гораздо удобнее, по крайней мере в моей компании. Прототипирование здесь не причем. Это более ранняя стадия.
Если вы считаете что мои слова - принуждение, то скажу более глобально. Плох тот разработчик, который не хочет учиться чему-то новому. Разработчика, который считает что он уже все знает, надо гнать в шею.
По поводу технологий согласен и повторюсь. Цель определяет средства, а не наоборот.
Мне хватило недели, чтобы разобраться.
впрочем, это исключительно проблемы моего собственного мозга, у вас конечно все получится намного быстрее)
1. тогда узкое место будет скорее всего не в трансформации
2. скорее всего можно будет грузить динамику httpRequest'ом и рисовать javascript'ом на закешированой :) после преобразования болванке (например корзина и т.д.)
было бы очень удобно скачать все файлы статьи одним архивом... хотя бы открыть в любимом xslt-редакторе (подсветка, навигация и т.п.)
http://parser.proc.ru/iso/xslt-1.zip
В шаблоне все пути прописаны от корня (делал на основе шаблона работающего на реальном сайте) поэтому либо перепишите их на относительные либо запускайте из под Apache.
В архиве входной XML-документ лежит в /xsl/document.xml
many thanks!
Но только одно замечание - вы забыли, как и все сторонники хслт, о самом важном вопросе, а именно: "нахрена козе баян?"
Система тратит время как на составление хмля, так и на его же парсинг, а где же плюсы? Каково принципиальное отличие от тех же пхпшных шаблонизаторов, от того же популярного смарти?
По тем же причинам я использую
- Parser, а не PHP
- Xara, а не Corel или Illustrator.
... список можно продолжать дальше.
Главное отличие в том, что XSLT является w3-стандартом, поддерживаемый всеми ведущими разработчиками. А смарти - это всего навсего одна из многих надстроек в PHP, которая даже в рамках PHP не рассматривается как стандарт.
приниципальное - трансформации можно гонять на клиенте а не на сервере ;)
хотя на практике мало кто этим пользуется...
- устаревшие броузеры не подцепят.
- если делать тупо в лоб, возникают траблы с поисковыми машинами
- Операция ресурсоемкая, на слабых комп. торможение заметно.
- XSLT в броузерах неполноценное. Навскидку - траблы с disable-output-escaping.
Мне кажется когда броузеры научаться парсить XSLT(2), дискуссия XSLT ver php-шаблонизаторы потеряет смысл.
P.S. Русские примеры xml/xpatch/xslt немного посеченгная версия английской версии. И, по хорошему, кучу нюансов эти примеры не отражают, искал в свое время некоторые решения по маленьким кусочкам, так что куча документации - это громкие слова
а потом в шаблоне <xsl:text>&site.about.title</xsl:text>, а каким образом Вы делаете вызов разных таблиц для разных локалей, через call-template или apply-template?
184209, Мурманская обл., г. Апатиты, ул.Такаято,
<br />
<a href="mailto:mail@domen.ru"><a href="mailto:mail@domen.ru">mail@domen.ru</a></a>
Насчет вызова разных таблиц - напишу в следующей статье. Там много тонкостей.
<xsl:template match="/node()"> </xsl:template>- шаблон для элемента /node() (корневого). Вместо /node() можно указать //document, т.к. он у нас являеться корневым узлом.меня немного пугают используемые вами xpath-выражения, если вы хотите взять корневой элемент почему бы не сделать это хотя бы так match="/document", во втором случае (//document) процессор не остановится на первом элементе, а продолжит бежать по всему дереву в поисках элемента document, а оно вам надо? старайтесь использовать // как можно реже, вы теряете в производительности
//document я указал, т.к. /document подглючивал у меня сегодня в IE.
Насчет // - согласен.
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
а дальше уже обращаться ко всем элементам самым простым способом
<xsl:template match="document">
...
</xsl:template>
но это уже каждый сам для себя решает, что хорошо, а что плохо)
Если кто-нибудь разобрался с этим, пожалуйста, поделитесь решением.
Я оперой давно не пользуюсь, поэтому скатать четко не могу, но проблем быть не должно.
<xsl:output method="xml"
...
/>
Именно из-за этого я делаю один шаблон для Оперы и еще один для остальных браузеров.
Ну а вообще в Опере 9.5 это уже поддерживается.
/node()выглядит как если бы вы хотели выбрать либо элемент, либо текстовый узел. Из контекста же ясно, что имеется в виду только элемент, тем более, что текстового узла в руте и быть не может. Возможно, разумнее использовать более узкий селектор*.В
descendant-or-self::*/@id = /node()/@id, как мне кажется, вся частьdescendant-or-self::*/лишняя, достаточно@id = /node()/@id, т. е.@id = /*/@id. А я так бы бы еще и переменную завел<xsl:variable name="current-section" select="/*/@id" />и сравнивал бы так:
@id = $current-section.Кстати, ведь браузеры по уму должны уметь отображать произвольный XML, если им дать соответствующий CSS для него. Т. е. насколько я понимаю, можно, во всяком случае, теоретически, не втискивать страничку в прокрустово ложе XHTML, а писать XML, точно отображающий структуру сайта. Не делать меню в виде
ul id="main-menu", а использовать свой тэг<menu>и задать ему в CSS все те опции, которые сейчас для#main-menuуказаны. Единственное ссылки и формы непонятно, как делать, хотя, в принципе, ничто не мешает смешивать свои теги со стандартным XHTML, разделяя их по namespaces.Про
<xsl:variable name="current-section" select="/*/@id" />я постараюсь поговорить позже. Это действительно удобнее. Просто, нужно будет еще объяснить переменные XSL.Насчет ul id="main-menu" - эта конструкция более валидная, чем
<menu><sample>
Some text <some element>some more text</some element>
</sample>
то селектор
/sample/node()[1]выбрал бы текстовый узел “Some text” (с пробельным материалом вокруг). Когда видишьnode(), это читается как «будем работать с текстом и элементами». У вас же работа с текстом не подразумевается.Минуса два. Первый - это то, что постоянно сталкиваешься с тем, что в каком-нибудь браузере что-то из xslt не реализовано. Конечно, чаще всего этим браузером становится Опера:) И второй минус - Яндекс не индексирует сделанные таким образом сайты. Т.е. бот заходит, но не индексирует. В чем проблема - пока не знаю. Буду очень признателен, если кто-нибудь поделится своим опытом в этой связи.
2. то что читает бот, не есть то, что видит пользователь. т.е. у вас в каждом xml может быть роман "Война и мир" но после xsl-трансофрмации в итоговую страницу ничего этого не войдет.
Это нормальная политика для поисковика, не давать себя спамить и т.д. для поддержания высокого качества выдачи.
Т.е. я сделал тупо текстовую версию сайта со всеми ссылками, переходами. Гугл захавал - я смотрю в кеше и вижу то, что и задумывал. Но вот яндекс, зараза...
Но зато они разрешили делать подмену заголовка специально для их робота - надо будет на стенку в рамочке повесить как официальное разрешение на клоакинг от яндекса:)
не в тему:
когда уже Хабр будет код подсвечивать и форматировать, а?
например есть список:
<list>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
</list>
Как его преобразовать в такое:
<table>
<tr>1<td></td><td>4</td></tr>
<tr>2<td></td><td>5</td></tr>
<tr>3<td></td><td>6</td></tr>
</table>
???
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/list">
<table>
<xsl:apply-templates select="item[count(preceding-sibling::item) <= count(following-sibling::item)]" mode="tr"/>
</table>
</xsl:template>
<xsl:template match="item" mode="tr">
<xsl:variable name="pos" select="ceiling(count(../item) div 2)"/>
<tr>
<xsl:apply-templates select="." mode="td"/>
<xsl:apply-templates select="following-sibling::item[$pos]" mode="td"/>
</tr>
</xsl:template>
<xsl:template match="item" mode="td">
<td><xsl:value-of select="."/></td>
</xsl:template>
</xsl:stylesheet>
1
2
3
XSLT:
В браузере открывать XML, XSLT-шный файл обозвать transform.xsl и бросить тудаже где файл.xml
Символы "<" нужно заменить на "<"
Сам код лучше обернуть в <code>...</code>.
Откуда такие грабли?
XML:
<?xml version="1.0" encoding="Windows-1251"?&rt;
<?xml-stylesheet type="text/xsl" href="transform.xsl"?&rt;
<list&rt;
<item&rt;1</item&rt;
<item&rt;2</item&rt;
<item&rt;3</item&rt;
</list&rt;
XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&rt;
<xsl:output method="html" encoding="windows-1251" doctype-system="http://www.w3.org/TR/html4/strict.dtd" doctype-public="-//W3C//DTD HTML 4.01//EN"/&rt;
<xsl:template match="/list"&rt;
<html&rt;
<body&rt;
<table&rt;
<xsl:for-each select="item[(position() - 1) mod 2=0]"&rt;
<tr&rt;
<td&rt;<xsl:value-of select="./text()" /&rt;</td&rt;
<td&rt;<xsl:value-of select="following-sibling::item/text()" /&rt;</td&rt;
</tr&rt;
</xsl:for-each&rt;
</table&rt;
</body&rt;
</html&rt;
</xsl:template&rt;
</xsl:stylesheet&rt;
Почему так криво то??? Какая нафиг подсветка синтаксиса, если оно простое то схавать не может?!!! Охренеть можно.... Раз в 5 минут и так криво!!! :D :D :D Я понимаю что надо предпросмотр юзать - но некогда мне - быстро написал пример и отправил.... Блин! Господа владельцы сайта, давайте я вам дам код для текстарии?? :D
1 - 2
3 - 4
5 - 6
Требовалось же
1 - 4
2 - 5
3 - 6
что сложнее
<xsl:variable name="totalItems"><xsl:value-of select="count(//list/item)"/></xsl:variable>
<xsl:variable name="totalItemsHalf"><xsl:value-of select="$totalItems div 2"/></xsl:variable>
<xsl:template match="//document">
<html>
<body>
<table border="1">
<xsl:apply-templates select="//list/item" mode="list"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="item" mode="list">
<xsl:variable name="cur">
<xsl:value-of select="position()"/>
</xsl:variable>
<xsl:variable name="next">
<xsl:value-of select="$totalItemsHalf + $cur"/>
</xsl:variable>
<tr>
<xsl:choose>
<xsl:when test="position() > $totalItems div 2"></xsl:when>
<xsl:otherwise>
<td><xsl:value-of select="text()"/></td>
<td><xsl:value-of select="parent::*/item[position() = $next]/text()"/></td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:template>
А так, если использовать CGI-склеивание XML с XSL то код получиться короче
Если трансформер не поддерживает стандарт, то не надо его использовать, это будет мучение одно.
Для рабочих проектов можно использовать все средства XSLT. В этом случае код уменьшается в разы и легче читается.
Я не говорю, что нужно использовать трансформацию на клиенте. Для этого пока нет достаточной поддержки со стороны браузеров.
match="item[position() div 2 = 1]"
я прав?
Забили помидорами под корень.
Взять, к примеру, проблему индексации "сайта с XSLT на клиенте" поисковиками, проблема? согласен. А как насчет бэк-офисов, интранет-систем? если вы решаете задачу в этих рамках, то проблем с индексацией у вас уже нет, потому что она там не нужна. Видите, одним злом сразу стало меньше. Нужно просто поискать правильную сферу применения.
Что касается РИТа, то я на нем не был, но я смотрел запись этого доклада, мне он смешным не показался, мне он показался очень любопытным. Интересно, а как вы оцениваете ваши собственные доклады, уважаемый Flack?
Нет, я неделаю интранет-проектов. Не интересно мне как-то. Так что для меня неиндексируемая технология не существует, уж извините :)
Я говорил не про доклад, а про обсуждение.
просто ваше утверждение звучит уж очень безапеляционно, мне захотелось немного его расшатать, и я не являюсь адвокатом Кудинова, но фраза показалась мне не очень дружелюбной)
P.S. Ты же сам докладчик, Лёха) прикинь, я напишу: было смешно, когда про это рассказывал Рыбаков (вроде)................ без обид)
а вопрос этот обсуждается и сейчас, а толковой информации как небыло так и нет.
как хоть назывался? и кто читал? а то Кудинова я в докладчиках не нашел. или это было в 2007?
Fade, не дадите ссылку на эту статью на другом сайте, где такой беды не приключилось?)