я тут потихоньку продолжаю изобретать велосипед
пусть нам надо образовать примерно такое меню:
PHP:
<div id="mmenu">
<div class="caps">главное меню</div>
<ul>
<li><a href="/news/">новости</a></li>
<li><a href="/phorum/">форум</a></li>
<li class="j-off">
<div class="caps j-baken"><a href="/gallery/">галерея</a></div>
<ul>
<li><a href="/gallery/girls/">девушки</a></li>
<li><a href="/gallery/auto/">машинки</a></li>
<li class="j-off">
<div class="caps j-baken"><a href="/gallery/animals/">зверьки</a></div>
<ul>
<li><a href="/gallery/animals/hedgehog/">ёжики</a></li>
<li><a href="/gallery/animals/tarantula/">тарантулы</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
пусть данные у нас представлены в следующем компактном виде:
PHP:
<menu title="главное меню">
<item title="новости" uri="/news/" />
<item title="форум" uri="/phorum/" />
<submenu title="галерея" uri="/gallery/">
<item title="девушки" uri="/gallery/girls/" />
<item title="машинки" uri="/gallery/auto/" />
<submenu title="зверьки" uri="/gallery/animals/">
<item title="ёжики" uri="/gallery/animals/hedgehog/" />
<item title="тарантулы" uri="/gallery/animals/tarantula/" />
</submenu>
</submenu>
</menu>
применим несколько модифицированный XSLT (назовём его YSLT):
PHP:
<t:template match="/mmenu">
<t:template name="m:maybelink" match="[@uri]" mode="self-data">
<a href="{@uri}">{@title}</a>
</t:template>
<div id="mmenu">
<div class="caps">
<m:maybelink>{@title}</m:maybelink>
</div>
<ul>
<t:template match="submenu">
<li class="j-off">
<div class="caps j-baken">
<m:maybelink>{@title}</m:maybelink>
</div>
<ul>
<t:apply-templates />
</ul>
</li>
</t:template>
<t:template match="item">
<li>
<m:maybelink>{@title}</m:maybelink>
</li>
</t:template>
<t:apply-templates />
</ul>
</div>
</t:template>
шаблоны могут располагаться не только в корневом элементе, что позволяет вкладывать их друг в друга. каждый шаблон доступен только внутри того элемента в котором определён.
<t:apply-templates /> применяет все доступные в даной точке шаблоны для которых не указан аттрибут mode ко всем детям.
для шаблона можно указать расширенное имя (например, m:maybelink) и потом вызывать его не через call-template, а в сокращённом виде: <m:maybelink>{@title}</m:maybelink>
если для шаблона указан аттрибут match, то будет проведена проверка указанного в нём условия и если совпадения не произошло - обработка будет произведена как буд-то вызова шаблона и не происходило: {@title}
xpath выражения допустимы как в аттрибутах, так и в текстовых узлах: <a href="{@uri}">{@title}</a>