.. / XSLT- примеры. Вып.6 Разворачиваем деревья

  1. xslt-recursive
  2. xslt-examples
  3. xslt-group
  4. client-side-xslt

Вывод данных в виде древовидных структур - задача достаточно типовая. Это может быть дерево сообщений в форумах и блогах, подобных этому, отображение карты сайта, различные многоуровневые рубрикаторы и т.п.  Способов организации таких структур в базах данных достаточно много, материалов в Сети тоже (см. пордборку в конце этой заметки).  Применительно к блогу рассмотрим самый простой (но не самый эффективный) способ, при котором в каждой записи хранится свой идентентификатор id и идентификатор родителя parentid. В виде XML ветка обсуждения в блоге имеет вид типа:

<item>
<topic id="1"  parentid="0" author="Иванов И.И." >  Лучший шаблонизатор - PHP</topic> 
<topic id="9"  parentid="8" author="Говорухо-Отрок С.П." >  Smarty - вот шаблонизатор</topic> 
<topic id="13"  parentid="9" author="Тынгылчав И.И." >  Нет Smarty это дурь</topic> 
<topic id="14"  parentid="13" author="Рабинович П.Е." >  Нет. дурь - это не Smarty</topic> 
<topic id="15"  parentid="9" author="Вышку Н.Н." >  Кто про дурь говорит?</topic> 
....................................................................................
....................................................................................
....................................................................................
</item>  

 Как приличные люди, мы должны организовать вывод этой ветки в виде семантически-грамотной верстки. Все сообщения в совокупности - ненумерованный список UL. Каждоее сообщение в отдельности - элемент ненумерованного списка LI. Каждое сообщение может иметь вложенный список сообщений - откликов.  

<ul>
     <li  id="1">  <h3>  Иванов И.И."</h3>      Лучший шаблонизатор - PHP
         <ul> 
             <li  id="9">  <h3>  Говорухо-Отрок С.П.</h3>  Smarty - вот шаблонизатор
                <ul> 
                  <li  id="13">  <h3>  Тынгылчав И.И.</h3>  Нет Smarty - это дурь</li> 
                     <ul> 
                        <li  id="14">  <h3>  Рабинович П.Е.</h3>  Нет. дурь - это не Smarty</li> 
....................................................................................
....................................................................................
                     </ul> 
                 </ul> 
             </li> 
         </ul> 
  </li> 
</ul>  

Шаблон для такого преобразования достаточно простой.

<xsl:template match="item">
     <ul> 
         <xsl:apply-templates select="topic[@parentid=0]" /> 
     </ul> 
 </xsl:template> 

 <xsl:template match="topic"> 
     <xsl:variable name="id" select="@id"/> 
     <li id="{@id}">   <h3>   <xsl:value-of select="@author"/>  пишет:</h3> 
         <p>   <xsl:apply-templates/>   </p> 
           <ul> 
               <xsl:apply-templates select="../topic[@parentid=$id]"/> 
           </ul> 
     </li> 
    
 </xsl:template>   

Первый шаблон (match="item") зацепляет первое сообщение ветки обсуждения у которого нет родителя. Т.е. parentid=0. Далее запускается рекурсивная процедура  (match="topic") которая выводит текущее сообщение и вытаскивает всех детей этой ветки. Т.е. сообщения являющиеся откликом непосредственно на текущее.

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

Как обычно, все исходники можно найти в архиве xslt-examples.zip в директории ex6

  1. 2008-12-08
  2. xslt-recursive
  3. xslt-examples
  4. xslt-group
  5. client-side-xslt
  1. phpclub.ru/faq/Tree?v=w5u - FAQ от phpclub. Способы хранения деревьев в базах данных
  2. www.alexandersperl.de/tutorials/css/sitemap.php - Hierarchical Sitemap with Dashed Lines (Отображение деревьев чистым CSS)
  3. javascript.ru/unsorted/tree - Грамотное javascript-дерево за 7 шагов (рецепты от javascript.ru)
  4. erum.ru/article/21 - Моя CSS-подборка. См. раздел "Деревья"
  5. www.realcoding.net/article/view/2766 - Отрисовка связанного дерева с помощью XSLT и XPath
  6. bassistance.de/jquery-plugins/jquery-plugin-treeview/ - jQuery plugin: Treeview (Отображение деревьев при помощи плагинов jquery)
Go Index Test