Как стать автором
Обновить

Многоуровневое меню в XSLT

Время на прочтение3 мин
Количество просмотров3.9K
Здравствуйте уважаемые Хабровчане. Хочу представить шаблон вывода многоуровневого меню, хотя, немного переделав, сойдет для вывода обычных деревьев. На нашем любимом сайте подобного не видел, в инете особо не искал. Для кого-то может показаться слишком легким, но надеюсь другим понадобиться.

Вот здесь уже разбиралась тема построение деревьев. В этом примере другая структура XML файла и заточка под другие задачи.

Начнем с XML файла. Структура не сложная. Каждый элемент состоит из идентификатора, идентификатора родительского элемента, ссылки и названия.


menu.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="menu.xsl"?> 
<root>
	<item id="1" idParent="0" link="#" title="Ссылка 1"/>
	<item id="2" idParent="1" link="#" title="Ссылка 2"/>
	<item id="3" idParent="1" link="#" title="Ссылка 3"/>
	<item id="4" idParent="2" link="#" title="Ссылка 4"/>
	<item id="5" idParent="2" link="#" title="Ссылка 5"/>
	<item id="6" idParent="1" link="#" title="Ссылка 6"/>
	<item id="7" idParent="6" link="#" title="Ссылка 7"/>
	<item id="8" idParent="6" link="#" title="Ссылка 8"/>
	<item id="9" idParent="0" link="#" title="Ссылка 9"/>
</root>

Не долго думая выведем шаблон преобразования

menu.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

	<!-- Настройка вывода -->
	<xsl:output method="html" encoding="utf-8" omit-xml-declaration="yes" doctype-system="about:legacy-compat"/>
	
	<!-- Основное преобразование -->
	<xsl:template match="/">
		<html lang="ru">
			<head>
				<title>Многоуровневое меню</title>
			</head>
			<body>
				<h1>Многоуровневое меню</h1>
				<ul>
					<xsl:apply-templates select="/root/item[@idParent=0]"/>
				</ul>
			</body>
		</html>
	</xsl:template>

	<!-- Шаблон вывода меню -->
	<xsl:template match="/root/item">
		<xsl:variable name="id" select="@id"/>
		<!-- Вывод элемента меню -->
		<li>
			<a href="{@link}">
				<xsl:value-of select="@title"/>
			</a>
			<!-- Если существют подпункты -->
			<xsl:if test="/root/item[@idParent=$id]">
				<ul>
					<xsl:apply-templates select="/root/item[@idParent=$id]"/>
				</ul>
			</xsl:if>
		</li>
	</xsl:template>

</xsl:stylesheet>

Шаблон преобразования состоит из двух частей. Первая выводит основные HTML теги и не особо интересна. Стоит только обратить внимание на вызов шаблона, который начинает вызов элементов с родительским идентификатором равным нулю.
Втора часть выводит пункт меню и проверяет, есть ли элементы с родительским идентификатором равным текущему идентификатору. Если есть, то рекурсивно вызывает этот же шаблон.

Естественно, пункты ссылающиеся на не существующих родителей отображаться не будут.

Сохраняем menu.xml и menu.xsl в одной папке и в браузере запускаем первый. Видим вот такую картину.

Вывод меню
image

P. S. Спасибо Dart за найденные ошибки.
Теги:
Хабы:
Всего голосов 5: ↑3 и ↓2+1
Комментарии5

Публикации

Истории

Ближайшие события

One day offer от ВСК
Дата16 – 17 мая
Время09:00 – 18:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн
Антиконференция X5 Future Night
Дата30 мая
Время11:00 – 23:00
Место
Онлайн
Конференция «IT IS CONF 2024»
Дата20 июня
Время09:00 – 19:00
Место
Екатеринбург
Summer Merge
Дата28 – 30 июня
Время11:00
Место
Ульяновская область