Навигационное меню XSLT - PullRequest
       10

Навигационное меню XSLT

1 голос
/ 11 августа 2011

У меня вопрос по XSL-преобразованию (XSLT-1).Я пробовал это с незапамятных времен, но у меня не получилось.

Я хочу построить стандартную навигацию по дереву веб-сайтов с XML и XSLT-1.Должны отображаться только элементы на пути к текущему элементу.если текущий элемент имеет дочерние элементы, должен быть открыт следующий узел.

Мой источник XML выглядит следующим образом:

<cat>
    <item id="0" name="1">
        <item id="1" name="1.1"></item>
        <item id="2" name="1.2"></item>
        <item id="3" name="1.3"></item>
        <item id="4" name="1.4">
            <item id="5" name="1.4.1">
                <item id="6" name="1.4.1.1"></item>
                <item id="7" name="1.4.1.2"></item>
                <item id="8" name="1.4.1.3"></item>
            </item>
            <item id="9" name="1.4.2"></item>
            <item id="10" name="1.4.3"></item>
        </item>
        <item id="11" name="1.5"></item>
        <item id="12" name="1.6"></item>
    </item>
    <item id="13" name="2">
        <item id="14" name="2.1"></item>
        <item id="15" name="2.2"></item>
    </item>
    <item id="16" name="3"></item>
</cat>

Теперь я хочу вызвать страницу с $ pageid =7 отправить по URL, и он должен показать некоторые выходные данные, подобные этому:

<ul>
    <li>1
        <ul>
            <li>1.1</li>
            <li>1.2</li>
            <li>1.3</li>
            <li>1.4
                <ul>
                    <li>1.4.1
                        <ul>
                            <li>1.4.1.1</li>
                            <li class="activeitem">1.4.1.2</li>
                            <li>1.4.1.3</li>
                        </ul>
                    </li>
                    <li>1.4.2</li>
                    <li>1.4.3</li>
                </ul>
            </li>
            <li>1.5</li>
            <li>1.6</li>
        </ul>
    </li>
    <li>2</li>
    <li>3</li>
</ul>

Если я вызову страницу с отправкой по URL $ pageid = 4, и он должен показать некоторые выходные данные, подобные этому:

<ul>
    <li>1
        <ul>
            <li>1.1</li>
            <li>1.2</li>
            <li>1.3</li>
            <li class="activeitem">1.4
                <ul>
                    <li>1.4.1</li>
                    <li>1.4.2</li>
                    <li>1.4.3</li>
                </ul>
            </li>
            <li>1.5</li>
            <li>1.6</li>
        </ul>
    </li>
    <li>2</li>
    <li>3</li>
</ul>

Надеюсь, мой пример понятен для всех.

У меня уже есть карта сайта и работает навигационная система, но этот, похоже, очень сложный и опытный.

Я пыталсяизменить примеры из Дерево навигации с XML и XSLT - но это не сработало.Он показывает только путь к элементу, но не все остальные.

Может ли кто-нибудь, имеющий опыт работы с XSLT-1, помочь мне с этим?

Или, может быть, у кого-то уже есть рабочее решение для публикации здесь?

Это было бы очень любезно.Спасибо всем за внимание.

Ответы [ 2 ]

2 голосов
/ 11 августа 2011

Задача здесь состоит в том, чтобы найти правильный тест для навигации внутри нового списка. Я думаю, что для данного элемента списка вы ищете этот вид теста (не совсем очевидный):

 "item and .//@id=$pageid"

Проверьте это преобразование.

[XSLT 1.0]

 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>
    <xsl:param name="pageid" select="4"/>

    <xsl:template match="/">
        <xsl:call-template name="Navigate"/>
    </xsl:template>

    <xsl:template name="Navigate">
        <ul>
            <xsl:apply-templates select="/cat/item" mode="Navigate"/>
        </ul>
    </xsl:template>

    <xsl:template match="item" mode="Navigate">
        <li>
            <xsl:apply-templates select="@id[.=$pageid]" mode="Navigate"/>
            <xsl:value-of select="@name"/>
            <xsl:if test="item and .//@id=$pageid">
                <ul>
                    <xsl:apply-templates select="item" mode="Navigate"/>
                </ul>
            </xsl:if>
        </li>
    </xsl:template>

    <xsl:template match="@id" mode="Navigate">
        <xsl:attribute name="class">
            <xsl:value-of select="'activeitem'"/>
        </xsl:attribute>
    </xsl:template>

</xsl:stylesheet>

результат для $ pageid = 4:

<ul>
   <li>1<ul>
         <li>1.1</li>
         <li>1.2</li>
         <li>1.3</li>
         <li class="activeitem">1.4<ul>
               <li>1.4.1</li>
               <li>1.4.2</li>
               <li>1.4.3</li>
            </ul>
         </li>
         <li>1.5</li>
         <li>1.6</li>
      </ul>
   </li>
   <li>2</li>
   <li>3</li>
</ul>

результат для $ pageid = 7:

<ul>
   <li>1<ul>
         <li>1.1</li>
         <li>1.2</li>
         <li>1.3</li>
         <li>1.4<ul>
               <li>1.4.1<ul>
                     <li>1.4.1.1</li>
                     <li class="activeitem">1.4.1.2</li>
                     <li>1.4.1.3</li>
                  </ul>
               </li>
               <li>1.4.2</li>
               <li>1.4.3</li>
            </ul>
         </li>
         <li>1.5</li>
         <li>1.6</li>
      </ul>
   </li>
   <li>2</li>
   <li>3</li>
</ul>

результат для $ pageid = 13:

<ul>
   <li>1</li>
   <li class="activeitem">2<ul>
         <li>2.1</li>
         <li>2.2</li>
      </ul>
   </li>
   <li>3</li>
</ul>
1 голос
/ 11 августа 2011

Я думаю, что логика заключается в том, что если элемент имеет выбранную страницу в качестве потомка или является выбранной страницей, то вы хотите просмотреть все дочерние элементы этого элемента...

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:param name="pageNum" select="13" />

   <xsl:template match="/cat">
      <ul>
         <xsl:apply-templates />
      </ul>
   </xsl:template>

   <xsl:template match="item">
      <li>
         <xsl:if test="@id=$pageNum">
            <xsl:attribute name="class">activeitem</xsl:attribute>
         </xsl:if>
         <xsl:value-of select="@name" />
         <xsl:choose>
            <xsl:when test="descendant-or-self::item[@id=$pageNum] and count(node()) > 0">
               <ul>
                  <xsl:apply-templates />
               </ul>
            </xsl:when>
         </xsl:choose>
      </li>
   </xsl:template>
</xsl:stylesheet>

Для 4 и 7 ожидаемый результат такой же, как показано в вопросе.Для 13 вывод выглядит следующим образом:

<ul>
    <li>1</li>
    <li class="activeitem">2
        <ul>
            <li>2.1</li>
            <li>2.2</li>
        </ul>
    </li>
    <li>3</li>
</ul>
...