Еще один раз о дереве с xsl

Не так давно я начал изучать xsl (и все с ним сопряженное). Лаконичность конструкций и его принадлежность к xml мне очень нравятся. Я не буду каждый раз писать, для чего я делаю то, или другое. Наверное, главной причиной является академический интерес, а потом уже все остальное.

В этот раз я решил трансформировать xml в дерево, которое можно просматривать с помощью броузера. Формат xml  я решил взять примерно такой, какой выплевывают mysql и mysqldump с ключем —xml при запуске.

Итак, входной документ xml, который нужно трансформировать в дерево:

items.xml
<items>

<item id=«0« caption=«Root«>

</item>

<item id=«1« caption=«level 1:1« parent=«0«>

</item>

<item id=«18« caption=«level 7:1« parent=«17«>

</item>

<item id=«19« caption=«level 6:2« parent=«16«>

</item>

</items>

XML Highlighter:
powered by dedestr

Далее сам шаблон xsl

tree.xsl
<xsl:stylesheet version=«1.0«>

<xsl:template match=«/items«>

<html>

<head>

</head>

<body>

<div>

<ul class=«tree«>

<xsl:apply-templates select=«/items/item[@id=0]«>

</xsl:apply-templates>

</ul>

</div>

</body>

</html>

</xsl:template>

<xsl:template match=«/items/item«>

<xsl:variable name=«parent« select=«@id«>

</xsl:variable>

<li>

<a>

<xsl:choose>

<xsl:when test=«/items/item[@parent=$parent]«>

<xsl:attribute name=«class«>
man

</xsl:attribute>

</xsl:when>

<xsl:otherwise>

<xsl:attribute name=«href«>
#

</xsl:attribute>

</xsl:otherwise>

</xsl:choose>

<xsl:value-of select=«@caption«>

</xsl:value-of>

</a>

<xsl:if test=«/items/item[@parent=$parent]«>

<ul>

<xsl:apply-templates select=«/items/item[@parent=$parent]«>

</xsl:apply-templates>

</ul>

</xsl:if>

</li>

</xsl:template>

</xsl:stylesheet>

XML Highlighter:
powered by dedestr

XPath выражение item[@id=0] в девятой строке предыдущего листинга выбирает элементы item, атрибут id которых равен 0 (что в нашем случае соответствует корню дерева). Такой элемент будет 1. Элемент xsl:apply-templates вызывает шаблон, который может принимать item для обработки.
Шаблон для обработки этого элемента начинается с шестнадцатой строки листинга.

Тут же стоит упомянуть, что дерево я решил делать в этом случае с помощью списков ul. В каждом узле дерева будет ссылка, которая, либо предназначена для свертывания дочерних узлов, либо именно для перехода к нужному контенту.
Для этого в двадцать первой строке реализуется выбор с помощью элемента xsl:choose. Если дочерние элементы у текущего есть, устанавливается атрибут class со значением man. Если же это лист дерева, устанавливается атрибут href, который, естественно, в реальных случаях вряд ли будет ссылаться на этот же документ, как сделано в примере.

Например, этот атрибут можно установить путем конкатенации с какой-либо строкой для ЧПУ с соответствующими настройками на сервере, или же ссылки могут храниться в файле узлов. В общем, как удобнее.

После того, как определился нужный параметр, выводим (тридцать первая строка листинга) заголовок узла.

После всего проделанного нужно определить, есть ли дочерние узлы у текущего. В принципе, можно было бы и не узнавать этого, и сразу перейти к выполнению шаблона для нужных элементов, а xsl-шаблонизатор сам бы разобрался, есть эти элементы, или нет. Но я все-таки заключаю вызов шаблона в условие, для того, чтобы в случае отсутствия у текущего узла дочерних, не вставлялись теги списка.

Этот небольшой шаблон позволяет вывести структурированное дерево.

Если взглянуть на пример, то даже назвать такое деревом вряд ли можно. Но, мы не забываем о том, что у нас есть css и javascript, и в другой записи, я покажу, как можно не используя изображений оживить наше дерево, например, в такое:

Деревце

Реклама
Запись опубликована в рубрике XSL. Добавьте в закладки постоянную ссылку.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s