1

我正在使用使用 VS.net 2010 创建的 web.sitemap 以及 XSLT 来创建一个干净的 CSS 菜单。
我已经修改了Cyotec的 xslt 以去除第一个节点,但是到目前为止我无法弄清楚如何在其中搜索以仅根据用户的角色显示链接。

XSLT 如下:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:map="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" exclude-result-prefixes="map">
  <xsl:output method="xml" encoding="utf-8" indent="yes"/>

  <xsl:template name="mapNode" match="/">
    <ul id="main-menu">
      <xsl:apply-templates select="*"/>
    </ul>
  </xsl:template>

  <xsl:template match="/*/*">
    <xsl:apply-templates select="*"/>
  </xsl:template>

  <xsl:template match="map:siteMapNode">
    <xsl:if test="/siteMap/SiteMapNode[@roles != 'Admin']">
            <li>
          <a href="{substring(@url, 2)}" title="{@description}">
            <xsl:value-of select="@title"/>
          </a>

          <xsl:if test="map:siteMapNode">
            <xsl:call-template name="mapNode"/>
          </xsl:if>

        </li>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

XML 如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
  <siteMapNode url="~/" title=""  description="Anon" roles="*">
    <siteMapNode url="~/anon.aspx" title="Anon"  description="Anon" roles="*" />
    <siteMapNode url="~/admin1.aspx" title="Admin1"  description="Admin Only" roles="Admin"/>
    <siteMapNode url="~/admin2.aspx" title="Admin2"  description="Admin Only" roles="Admin">
      <siteMapNode url="~/admin3.aspx" title="Admin3"  description="Admin Only" roles="Admin"/>
    </siteMapNode>
  </siteMapNode>
</siteMap>

我只想输出角色的 url 标题和描述!= Admin 没有搜索,一切都可以正常工作。
有没有人能够阐明“if”功能,或者提出更好的方法来实现这一点?
提前致谢

4

1 回答 1

2

您当前xsl:if条件的问题....

<xsl:if test="/siteMap/SiteMapNode[@roles != 'Admin']"> 

....是第一个正斜杠意味着它是一个绝对路径,从根元素开始,所以所有的xsl:if都是说是否有任何SiteMapNode,直接在siteMap元素下,不是管理员角色. 这意味着在您的情况下它总是正确的。

你真的只想检查当前元素的角色

<xsl:if test="@roles != 'Admin'"> 

但是,有一种更简洁的方法可以做到这一点。删除xsl:if条件,只使用一个单独的模板来匹配管理员角色元素,并忽略它们。

<xsl:template match="map:siteMapNode[@roles='Admin']"/>

这是完整的 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:map="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" exclude-result-prefixes="map">
   <xsl:output method="xml" encoding="utf-8" indent="yes"/>

   <xsl:template name="mapNode" match="/">
      <ul id="main-menu">
         <xsl:apply-templates select="*"/>
      </ul>
   </xsl:template>

   <xsl:template match="/*/*">     
      <xsl:apply-templates select="*"/>     
   </xsl:template>     

   <xsl:template match="map:siteMapNode[@roles='Admin']"/>

   <xsl:template match="map:siteMapNode">
      <li>
         <a href="{substring(@url, 2)}" title="{@description}">
            <xsl:value-of select="@title"/>
         </a>
         <xsl:if test="map:siteMapNode">
            <xsl:call-template name="mapNode"/>
         </xsl:if>
      </li>
   </xsl:template>
</xsl:stylesheet>

应用于您的示例 XML 时,将输出以下内容

<ul id="main-menu">
   <li>
      <a href="/anon.aspx" title="Anon">Anon</a>
   </li>
</ul>

Do note the template that matches the admin role element is more specific that the template that matches any SiteMapNode element and so the XSLT processor will give priority to this when matching.

于 2012-09-24T06:33:37.097 回答