Полезные ссылки на документацию по XSL

#
Re: Полезные ссылки на документацию по XSL
Stepan0v, вот такой код для решения на XSL. Он получился несколько более изящным, чем та идея, которую я вчера описывал словами:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:hostcms="http://www.hostcms.ru/" exclude-result-prefixes="hostcms">
   <xsl:output xmlns="http://www.w3.org/TR/xhtml1/strict" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" encoding="UTF-8" indent="yes" method="html" omit-xml-declaration="no" version="1.0" media-type="text/xml"/>


   <!--Выберем первые 10 элементов к показу-->
   <xsl:variable name="items" select="/informationsystem/informationsystem_item[position() &lt;= 10]"/>


   <!--корневой темплейт-->
   <xsl:template match="/informationsystem">

      <!--Выводим элементы, которые лежат прямо в корне ИС, если таковые попали в выборку-->
      <xsl:apply-templates select="$items[informationsystem_group_id = 0]"/>

      <!--Матчим корневые группы, по условию, что id самих групп или их (под-...)подгрупп есть среди informationsystem_group_id у выбранных ранее элементов-->
      <xsl:apply-templates select="informationsystem_group[@id = $items/informationsystem_group_id or .//informationsystem_group/@id = $items/informationsystem_group_id]"/>

   </xsl:template>


   <!--Общий шаблон для групп-->
   <xsl:template match="informationsystem_group">

      <!--Определеяем уровень вложенности текущей группы. Для групп в корне он будет равен 1-->
      <xsl:variable name="level" select="count(ancestor-or-self::informationsystem_group)"/>

      <!--Рисуем div с отступом слева. Чисто для красоты.
      Для групп верхнего уровня отступ не делаем, поэтому от $level отнимаем едничку-->
      <div style="margin-left:{20*($level - 1)}px">

         <!--Создаем html-элемент Заголовок нужного нам уровня.
         Внимание! Это не будет корректно работать, если глубина вложенности групп больше 6-->
         <xsl:element name="{concat('h', $level)}">

            <!--Выводим название текущей группы-->
            <xsl:value-of select="name"/>
         </xsl:element>

         <!--Выводим элементы текущей группы, если таковые попали в выборку-->
         <xsl:apply-templates select="$items[informationsystem_group_id = current()/@id]"/>

         <!--Матчим подгруппы текущей группы, по условию, что id самих подгрупп или их подподгрупп есть среди informationsystem_group_id у выбранных инфоэлементов-->
         <xsl:apply-templates select="informationsystem_group[@id = $items/informationsystem_group_id or .//informationsystem_group/@id = $items/informationsystem_group_id]"/>
      </div>

   </xsl:template>


   <!--Темлейт для вывода элементов-->
   <xsl:template match="informationsystem_item">

      <p>
         <!--Выводим название инфоэлемента-->
         <xsl:value-of select="name"/>
      </p>

   </xsl:template>

</xsl:stylesheet>


Этот код, на основе вашего XML порождает следюущий html-документ:
<div style="margin-left:0px">
   <h1>Тексты (книги, статьи, рецензии, интервью)</h1>
   <div style="margin-left:20px">
      <h2>1963</h2>
      <p>Раймон Руссель или ужас пустоты</p>
   </div>
   <div style="margin-left:20px">
      <h2>1966</h2>
      <p>Бергсонизм</p>
   </div>
   <div style="margin-left:20px">
      <h2>1974</h2>
      <p>28 ноября 1947 г. Как сделать себя телом без органов? (совместно с Ф.Гваттари)</p>
   </div>
   <div style="margin-left:20px">
      <h2>1994</h2>
      <p>Вещь в себе у Канта (совместно с Ferdinand Alquie, Louis Guillermit and Alain Vinson)</p>
   </div>
   <div style="margin-left:20px">
      <h2>1996</h2>
      <p>Актуальное и виртуальное</p>
   </div>
   <div style="margin-left:20px">
      <h2>2000</h2>
      <p>Алфавит Жиля Делеза</p>
   </div>
</div>
<div style="margin-left:0px">
   <h1>Публикации под редакцией Ж.Делёза</h1>
   <p>Instincts et institutions</p>
</div>
<div style="margin-left:0px">
   <h1>Диссертации, защищенные под руководством  Ж.Делёза</h1>
   <p>Alliez, Eric. "Naissance et conduites des temps capitaux"</p>
</div>
<div style="margin-left:0px">
   <h1>Обращения и петиции, подписанные Ж.Делёзом</h1>
   <p>«Призыв к рабочим и служащим восстать против организованной сети расистов, опирающихся на властные структуры» (против анти-Алжирского движения)</p>
</div>
<div style="margin-left:0px">
   <h1>Dubia</h1>
   <div style="margin-left:20px">
      <h2>1977</h2>
      <p>Вводные и заключительные комментарии…</p>
   </div>
</div>


Однако, несмотря на кажущуюся простоту и элегантность он плох.
Вот эти выражения
informationsystem_group[@id = $items/informationsystem_group_id or .//informationsystem_group/@id = $items/informationsystem_group_id]
- они очень дорогие, профайлер показывает, что 77% времени выполнения всего шаблона уходит на вычисление этих выражений. При чем, затраты времени в процентном отношении увеличиваются, при росте числа элементов в первоначальной выборке.
Заказов не беру. Консультирую редко.
#
Re: Re: Полезные ссылки на документацию по XSL
Kotoff, спасибо. Буду разбираться.
Но у же сейчас вижу, что первые 10 элементов
<!--Выберем первые 10 элементов к показу-->
    <xsl:variable name="items" select="/informationsystem/informationsystem_item[position() &lt;= 10]"/>

Не являются десятью элементами, которые на самом деле надо показывать.
Проблема в том, что показывать мне надо элементы по группам. Т.е. сначала элементы из первой группы, потом из второй, потом из третьей и т.д.
Но элементы в XML расположены не по группам. Они сначала из всех групп собраны в одну кучу, а потом уже в этой куче рассортированы по порядку. В итоге мы имеем:
1й элемент первой группы →
1й элемент второй группы →
1й элемент третьей группы →
2й элемент первой группы →
2й элемент второй группы и т.д.
Поэтому в html в каждой подгруппе получилось по одному элементу, хотя на самом деле их больше.

Мне же нужно сначала взять все элементы из одной группы, потом, если не хватает, переходить к следующей и т.д.
#
Re: Полезные ссылки на документацию по XSL
Stepan0v, но вы же сами сказали, на предыдущей странице, что вам нужно сохранить общую сортировку. Вот я и выбрал первые 10 элементов по общей сортировке.
Заказов не беру. Консультирую редко.
#
Re: Полезные ссылки на документацию по XSL
Stepan0v писал(а):
Мне же нужно сначала взять все элементы из одной группы, потом, если не хватает, переходить к следующей и т.д.
Тогда все-таки надо предварительно выбирать id нужных элементов в ТДС и передавать в XML только их.
ИМХО, средствами одного лишь XSL такую задачу не решить.
Если, конечно, не рассматривать такие экзотические способы как EXSLT Nodeset(). Оно, конечно, позволит, но это будет очень ресурсоемко.
Заказов не беру. Консультирую редко.
#
Re: Полезные ссылки на документацию по XSL
Kotoff писал(а):
вы же сами сказали, на предыдущей странице, что вам нужно сохранить общую сортировку.

Да, сохранить, но в рамках групп ) Т.е. если выводить не подряд, а по группам, то всё сохраняется...

Эх... не хотелось лезь в этот ORM... Спасибо!

P.S. Уж думаю, не сделать ли пока заглушку на JQuery со страницами, пока дело с мертвой точки не сдвинется.
#
Re: Re: Полезные ссылки на документацию по XSL
Kotoff, а можно ли как-то пересобрать массив ИЭ, чтобы они в XML выводились не в том порядке, в котором сейчас (все подряд), а по группам? Т.е. сначала из одно группы, потом из второй и т.д. А внутри групп уже та сортировка, которая и раньше применялась.

Я вот попробовал, но ничего у меня не вышло )
#
Re: Полезные ссылки на документацию по XSL
Stepan0v писал(а):
а можно ли как-то пересобрать массив ИЭ, чтобы они в XML выводились не в том порядке, в котором сейчас (все подряд), а по группам?
Весьма сомнительно. Можно попробовать через хуки, но на это даже я не стану заморачиваться, боюсь ниасилю )
Да и ведь на самом-то деле не надо вам этого!

Вы уже постучитесь в аську с доступами, да я вам прямо на месте наваяю частное решение задачки на php+xsl. А то чего мы тут уже неделю теоретизируем...
Заказов не беру. Консультирую редко.
#
Re: Полезные ссылки на документацию по XSL
Здравствуйте. Мне нужно в xsl-шаблоне в JavaScript получить значения двух переменных xml.
Не хочет код работать. Что я не так делаю? Версия системы v.6.
<SCRIPT>
               <xsl:comment>
                  <xsl:text disable-output-escaping="yes">
                     <![CDATA[
                     function myfunct(itemname, itemprice) {
                     VVC.gui.addCreditInfoWindow('http://mysite.ru/shop/cart', 'http://mysite.ru/shop/' , {"name":"itemname", "amount":itemprice});
                     }
                     
               myfunct('<xsl:value-of disable-output-escaping="yes" select="name"/>', '<xsl:value-of disable-output-escaping="yes" select="price"/>');
                     ]]>
                  </xsl:text>
               </xsl:comment>
            </SCRIPT>
iNikSite - дизайн и фронтенд разработка
Модератор
#
Re: Полезные ссылки на документацию по XSL
iNik,
и не получите, оборачивайте код в функцию с N аргументами и вызывайте эту функцию отдельно, передавая в нее параметры через xsl:value-of. На форуме точно пару раз обсуждалось.
#
Re: Полезные ссылки на документацию по XSL
HostCMS писал(а):
и не получите, оборачивайте код в функцию с N аргументами и вызывайте эту функцию отдельно, передавая в нее параметры через xsl:value-of. На форуме точно пару раз обсуждалось.

Спасибо. Нашел простое решение этой задачи.
<a href="{/shop/url}cart/?add={@id}" onclick="VVC.gui.addCreditInfoWindow('/shop/cart');" id="VVC_INFO_ELEMENT" amount="{price}" vvcpattern="~?~" class="myButton2"><b>Купить в кредит за ~?~ руб. в месяц</b></a>
iNikSite - дизайн и фронтенд разработка
Авторизация