XSLT导航菜单

时间:2011-08-11 02:15:19

标签: xml xslt xhtml tree navigation

我对XSL-Transformation(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>

现在我想通过URL调用$ 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>

如果我通过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>

希望我的例子对所有人都是可以理解的。

我已经有一个站点地图和面包屑导航工作,但这个似乎非常棘手且经验丰富。

我尝试修改Tree navigation with XML and XSLT中的示例 - 但效果不佳。它只显示项目的路径,但不显示其余的路径。

XSLT-1有经验的人可以帮助我吗?

或许有人已经有了一个可以在这里发布的工作解决方案?

非常友好。谢谢大家的关注。

2 个答案:

答案 0 :(得分:2)

这里的挑战是找到在新列表中导航的正确测试。对于给定的列表项,我认为您正在搜索此类测试(不是很明显):

 "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 :(得分:1)

我认为逻辑是,如果某个项目将所选页面作为后代,或者是所选页面,那么您希望查看该项目的所有子项目。

这是我的尝试......

<?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>