XSLT 导航菜单

发布于 2024-11-29 03:27:49 字数 3105 浏览 1 评论 0原文

我有关于 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>

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

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

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

我尝试修改 使用 XML 和 XSLT 的树导航 中的示例 - 但它效果不佳。它仅显示该项目的路径,而不显示其余部分。

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

或者也许有人已经有一个可行的解决方案可以在这里发布?

这将是非常友善的。感谢大家的关注。

I have a question on XSL-Transformation (XSLT-1). I am trying it since days, but I didn't get it to work.

I want to build a standard website tree navigation with XML and XSLT-1. It should only show the items on the path to the current item. if the current item has child-items, the next node should be opened.

My XML source is like this:

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

Now I want to call a page with an $pageid=7 send by URL, and it should show some output like this:

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

If I call a page with an $pageid=4 send by URL, and it should show some output like this:

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

Hopefully my example is understandable for all.

I already got a sitemap and a breadcrumb navigation working, but this one seems to be very tricky and experienced.

I tried to modify the examples from Tree navigation with XML and XSLT - but it didn't worked well. It only shows the path to the item, but not the rest.

Can somebody experienced with XSLT-1 help me with it?

Or maybe somebody has already a working solution to post here?

It would be very kind. Thank you all for your attention.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

嗼ふ静 2024-12-06 03:27:49

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

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

The challenge here is to find the correct test for navigating inside a new list. For a given list item, I think you are searching for this kind of test (not really obvious):

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

Check this transform out.

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

result for $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>

result for $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>

result for $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>
魄砕の薆 2024-12-06 03:27:49

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

这是我的尝试...

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

I think the logic is that if an item has the selected page as a descendent, or is the selected page, then you want to see all child items of for that item.

Here is my attempt...

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

For 4 and 7 the expected output is as shown in the question. For 13, the output is as follows:

<ul>
    <li>1</li>
    <li class="activeitem">2
        <ul>
            <li>2.1</li>
            <li>2.2</li>
        </ul>
    </li>
    <li>3</li>
</ul>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文