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

в 9:21, , рубрики: XML, xslt, метки: ,

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

Вот здесь уже разбиралась тема построение деревьев. В этом примере другая структура 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> 		</li> 		<!-- Если существют подпункты --> 		<xsl:if test="/root/item[@idParent=$id]"> 			<ul> 				<xsl:apply-templates select="/root/item[@idParent=$id]"/> 			</ul> 		</xsl:if> 	</xsl:template>  </xsl:stylesheet> 

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

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

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

Вывод меню
image

Автор: parsek

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js