XSL
Задаем вопросы по XSL: чем он лучше остальных шаблонизаторов, примеры решений и хороших практик, инструменты. Самые интересные вопросы будут добавляться прямо в статью. Большая просьба не задавать вопросов вроде «какую книгу по XSL советуете прочитать», «где найти уроки для начинающего кодера», «помогите найти ошибку в коде» и тому подобное — все это останется без ответа, по крайней мере с моей стороны.
есть идея собрать сложные варианты логики, не реализуемой простым шаблонированием. чтобы вывести как исключения. а всё что не исключение, делать через match. хочеться услышать различные варианты и мнения за/против. можно с примерами. простите, просто больная тема 🙂
Хм, не понял, о чем ты. Имеется в виду использование xslt extensions?
Сильно ли влияют конструкции вида <xsl:text>Какой-то текст</xsl:text> и <xsl:value-of select=»concat(‘my_class ‘, $_class)» /> на производительность если шаблоны пропускаются через парсер (saxon или libxslt), а не отдаются на «растерзание» браузера? 🙂
Можешь предложить какие-нибудь рекомендации по оптимизации xslt-шаблонов?
Пока, к своему сожалению, я не копался в производительности XSL-трансформеров, да и рекомендаций каких-то конкретных не встречал (в основном только по внешнему виду и организации шаблонов). Могу только обратить внимание, что в Apache Xalan есть такая вещь как предварительная компиляция XSL-шаблона в Java-класс, что повышает производительность. Подробнее читайте на страничке XSLTC.
Сергей, оправдана ли такая «экономия на спичках»: вместо ab писать ?
Блин, подсказки под формой добавления коммента не хватает 🙁
Сергей, оправдана ли такая «экономия на спичках»: вместо <xsl:text>a</xsl:text><xsl:value-of select=»text()»/><xsl:text>b</xsl:text> писать <xsl:value-of select=»concat(‘a’, text(), ‘b’)»/>?
Аналогично предыдущему комментарию: по скорости исполнения сказать не могу, но я бы использовал второй вариант.
Сергей, используете ли в работе XSLT и XPath второй версии?
Если да, то, если не секрет, каким процессором пользуетесь для обработки?
Если нет, то почему?
Вообще, каковы, на ваш взгляд, перспективы этих технологий? Два с половиной года назад они получили статус рекомендаций w3c, но весь buzz вокруг них, кажется, утих ещё году в 2005-ом.
Второй версией пока не пользовался. Насколько я знаю, ее поддерживает только Saxon, а все популярные языки программирования (PHP, Parser, Python) используют libxsl, который понимает только первую версию. О перспективах пока сложно говорить из-за указанной слабой поддержки со стороны трансформеров.
Суть: есть такой вызов , сам шаблон лежит где-то в пределах проекта. Можно ли перед вызовом делать проверку на существование вообще этого шаблона и если его такого нет, то просто не вызывать (всё это для того, чтобы не выдавалась ошибка при отсутствии такого шаблона)?
Как проверить — не знаю, стандартных средств не нашел, возможно, есть в каких-нибудь расширениях есть. Я бы посоветовал в таком случае вместо
< использовать . Тогда вы создать заглушку, которая ничего не выводит, а также сможете перекрыть ее шаблоном, который что-то делает. Можно, конечно, создать заглушку и для именованного шаблона, но в описанном мной примере больше гибкости.
Расскажите каким образом у вас организованы файлы проекта? Как формируете лайот страниц? Я ищу решение, гибкое простое и более-менее универсальное. Решил изучить CodeIgniter, для практики переведя один из проектов, и уже разочаровыван в модели MVC. Возможно, решение — это xsl? Я не хочу заморачиваться на ООП ради ООП.
Структура такая:
main.xsl — основной шаблон, в нём описываются все основные блоки лэйаута. common.xsl — всякие сервисные штуки, вроде генерации меню из XML-структуры, вывод дат, обработка строк и т.д. html.xsl — вывод HTML тэгов. Каждый контентный XML-тэг обязательно проходит через свой шаблон, фильтруя ненужные данные и добавляя нужные атрибуты и классы. Если мне нужно вывести содержимое какого-нибудь блока, я матчу его на шаблон вроде
<xsl:apply-templates select="myblock" mode="html_inner"/>
. Есть шаблон<xsl:template match="*" mode="html_inner">
, который просто начинает матчить правильные элементы (определяются в энтити) внутри переданного контекста через шаблон<xsl:templates match="*" mode="html">
. Таким образом, каждый элемент у меня обязательно проходит через шаблон, а я, в свою очередь, могу в нужный момент перехатить необходимые элементы, перекрыв шаблон, и вывести то, что мне нужно.Здравствуйте, Сергей. Для верстки вы используете eclipse + aptana. А чем пользуетесь для работы с xslt? Altova, Oxygen или может быть один из плагинов для eclipse? И если можно почему вам выбор пал на тот или иной инструментарий?
Использую стандартный XSL редактор из Web Tools Project. В принципе, мне его хватает, так как нужен только code complete и Zen Coding. Для дебага XSL-шаблонов в CMS сейчас пишу (ну ладно, пока думаю о нём, но уже есть первая альфа-версия) свой инструмент.
Здравствуйте Сергей, прошу минутку вашего внимания, нужна ваша помощь!
Я изучаю XHTML и CSS уже больше полугода, вышел на более менее неплохой уровень, теперь хочу двигаться дальше.
Помогите разобраться, что раньше мне нужно начать изучать, JavaScript(немного изучал, более менее имею представление) или XML(никогда не изучал.)
У меня есть много хорошей литературы по обоим предметам, только вот не знаю от куда начать, так как времени уйдет много и чтоб потом не возвращаться назад и не начинать учить что-то из этих языков заново, понимая, что сначала нужно было уделить время другому, я прошу вашей помощи, помогите пожалуйста начинающему!
Спасибо!
Здравствуйте. следующий вопрос:
скажем есть структура xml документа.
… (тут какие то ноды с какой-то инфой)
… (тут какие то ноды с какой-то инфой)
… (остальное ноды Sof)
соответственно мне надо пробежаться по всем нодам Soft и вывести красивенько id нода Soft и ниже все его остальные хар-ки, которые находятся внутри него («… (тут какие то ноды с какой-то инфой)»). Факт в том, что не все характеристики повторяются в Soft.
Как же написать xsl преобразование, чтобы он вывел все ноды Soft со всеми их характеристиками не обращаясь а каждой по tag name ?
Тэги побились, лучше отправьте мне пример по почте.
Сергей, что ты можешь сказать об использовании xsl браузерами? Я говорю не о вызове преобразования джаваскриптом, а об этом .
Теоретически с этим спокойно справляются последние ff, opera, chrome, а и ie так вообще с 6-й версии.
Так вот почему клиентский xsl не распространен? Мало специалистов, нагрузка на браузер, плохая поддержка в браузерах (например, мобильных) или что-то еще? Есть ли у клиентского xsl перспективы?
теги съело: … а об этом xsl-stylesheet type=»text/xsl» href=»some.xsl» (processing instruction)
Потому что есть поисковики, которые не смогут правильно проиндексировать xml вашего сайта. Ещё лично я вижу кучу проблем с производительностью. Например, на моих сайтах исходный xml страницы весит раз в 5 больше чем результат преобразования, не говоря уже о десятках xsl-файлов, из которых состоит шаблон.
Добрый день, Сергей.
Посоветовали к вам обратиться — что немного пугает — неужели эту задачу не так просто решить…
Пытаюсь написать яваскрипт функцию, которая должна получить значение из xsl — но с определённым условием — с заданным атрибутом @name.
Пример такой: нужно получить значение из таблицы, где TROW/@name=path_id
Пишу вот так — не работает
function SetUUID()
{
path_id = ‘2’;
valuuid = »;
alert(valuuid);
}
А вот так она работает
function SetUUID()
{
path_id = ‘2’;
valuuid = »;
alert(valuuid);
}
Подскажите, пожалуйста, как значение переменной подставить в xsl?
Да уж — самая значимая часть процедуры съелась)
valuuid = ‘< xsl:value-of select=»//TABLE/TROW[@name=path_id]/TDATA[@name=’NAME’]»/ >’;
valuuid = ‘< xsl:value-of select=»//TABLE/TROW[@name=’2′]/TDATA[@name=’NAME’]»/ >’;
А что такое path_id? Переменная? Потому что сейчас запрос выглядит так: достать TROW, у которого значение атрибута name равно значению дочернего тэга path_id.
Возможно, вы имели в виду либо @name=$path_id, либо @name=current()/path_id
path_id — да, переменная, и на самом деле выглядит так:
path_id = document.getElementById(‘path’).value;
То есть фактически я хочу, чтобы вместо двойки можно было подставить произвольное число.
@name=current()/path_id — ничего не дало,
@name=$path_id — ошибка что переменная $path_id не определена
Я толком не понимаю, в каком контексте используется этот xpath-запрос и откуда переменная берётся. Вы через JS хотите его выполнить? Тогда почему вы используете XSL-конструкцию
<xsl:value-of />
вместоdocument.evaluate()
?Сергей, добрый день!
Мне подсказали, как можно с другой стороны подойти к решению задачи:
переделать template TABLE — добавив каждой ячейке td уникальный id, и уже по id искать значение.
Но всё равно любопытно — можно ли было сделать без этих доработок…
document.evaluate(), как я понимаю, при поиске использует результирующий html документ?
Можно делать поиск по xsl документу?
Дополнительно на почту отправляю собранный пример — связку xml и xsl — большая просьба помочь разобраться)
Сергей, привет!
> Например, на моих сайтах исходный xml страницы весит раз в 5 больше чем результат
> преобразования, не говоря уже о десятках xsl-файлов, из которых состоит шаблон.
Можешь привести пример для сравнения? исходный XML и XHTML после трансформации. Сами шаблоны не интересуют. Я пытаюсь понять, что может быть причиной такой разницы, что может понадобиться в исходном XML.
В исходный XML выводится информация из стандартного обработчика, который присутствует на десятке страниц. Просто на каждой странице разная информация пользователю выдаётся.
Сергей, я так и не понял, почему исходный XML может быть во много раз больше.
Но вот еще вопрос по XSL.
Забавно, но я нигде не могу точно найти, iPad поддерживает клиентские трансформации? iPod не поддерживает точно. Но про iPad точного ответа не могу найти. Судя по этому топику, поддержка есть: http://forums.appmobi.com/viewtopic.php?f=8&t=115
Добрый день Сергей!
Вопрос может показаться тупым, заранее извини. Преамбула. Есть список элементов, а есть подробная информация об одном элементе из этого списка. Для отображения того или другого можно использовать один xsl-шаблон и путем матчинга/условий отображать либо список, либо элемент. Но можно использовать и два шаблона — один для отображения списка, второй для отображения элемента.
Должен ли xsl-шаблон быть «строго-специализированным» или он может обрабатывать разнородные (по логике) данные, используя match/if/choose/when/otherwise?
г-н Тараканофф, я придерживаюсь принципа duck typing: если данные выглядят похоже на то, что мне нужно, то я пропускаю их через один шаблон, а не через несколько, которые делают лдно и тоже. Это хорошо и для поддержки проекта, и для производительности.
Добрый день Сергей!
При матчинге темплейтов, где следует (даже, где правильнее) определять условия матчинга — apply-templates select=»путь[условие]» или template match=»путь[условие]»?
г-н Тараканофф, правильнее делать apply-templates select=»путь[условие]»
Вообще-то оба варианта правильные, все зависит от обстоятельств.
http://chikuyonok.ru/xsl/#comment-1429 — а можете поподробнее расписать взаимодействие этих трех шаблонов?
Я так понял, что сначала вы готовите удобное для вывода дерево и только потом преобразуете его в html, и все это в течение одного цикла, так? Обычно, ребята результаты одного шаблона отдают на вход другому, что выглядит немного избыточно. Мне показалось, что у вас как-то иначе. Расскажите? Спасибо.
Добрый день Сергей!
Извини за беспокойство, у меня новый вопрос. Описание. Некоторое количество блоков с информацией нужно «отшаблонить» разными шаблонами. Тег каждого блока имеет свое уникальное наименование. Просто применяю apply-templates (без атрибута select) и затем применяю template (с атрибутом match=»наименование-тега-блока»). Каждый блок обрабатывается каким-то своим шаблоном.
В будущем понадобилось «обернуть» шаблон каждого блока, дополнительной «оберткой» (тегом div). Писать одну и ту же «обертку» во все шаблоны блоков не хочется.
Я поступил таким образом. Применил apply-templates с атрибутом mode=»blocks-wrapper». Добавил дополнительный шаблон template c атрибутом mode=»blocks-wrapper». В дополнительном шаблоне добавил теги «обертки» (div) и внутри «обертки» применил apply-templates (без атрибута select).
В результате каждый блок «обертывается» и затем обрабатывается каким-то своим шаблоном.
Это оптимальный вариант? Если нет, то пожалуйста, напиши своё решение.
Очень извиняюсь, в словах «…В дополнительном шаблоне добавил теги “обертки” (div) и внутри “обертки” применил apply-templates (без атрибута select)…» немного ошибся. Там в apply-templates есть-таки атрибут select=»current()».
Есть какие-то стандартные способы привести html к xml для обработки XSL шаблонами?
Суть проблемы: нужно посылать на сервер кусок html кода (страница с доктайпом xhtml strict, но поставить ей заголовок application/xhtml+xml пока нет возможности, сервер отдает ее как text/html). Кусок кода берется яваскриптом как свойство innerHTML одного блока и передается на сервер (через AJAX запрос). На сервере простеньких php-скриптик запускает XSLT-преобразование и отдает XML дальше. Все работает нормально, пока в куске html кода не встречаются самозакрывающиеся теги типа img или br 🙂 В innerHTML закрывающий тег для таких тегов отсутсвует (браузер приводит все к html)
Можно придумать какую-то регулярку, конечно. Но вдруг уже есть такие велосипеды (tidy?) Или все таки стоит научить сервер отдавать application/xhtml+xml для нужной страницы?
Есть еще вариант передавать кусок DOMа на сервер и не париться с XSL, но текущий XSL-стиль очень органично делает то, что надо 🙂
Можно сериализовать дерево в XML: https://developer.mozilla.org/en/XMLSerializer
Сергей, какой XML для описания HTML-форм используете? Спасибо
Сергей, можете пояснить чем существенно отличаются два выражения, в одном из которых один предикат с несколькими условиями, а в другом двойной предикат? Как лучше писать и почему?
1) result[@size = ‘3’ and @color = ‘red’]
2) result[@size = ‘3’][@color = ‘red’]
Я точно не знаю, но на мой взгляд они эквивалентны друг другу. Я использую вариант номер 1, так как его потом проще исправлять (например,
end
заменить наor
).