I am using the web.sitemap which is created using VS.net 2010 along with a XSLT to create a clean CSS-able menu.
I have modified the xslt from Cyotec to strip out the first node however I am so far unable to work out how to search within to display only the links depending on the role of the user.
The XSLT is as below:
<?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>
The XML looks like this:
<?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>
I am wanting to only output the urls titles and descriptions where roles != Admin
Everything works fine without the search.
Is anyone able to shed some light on the ‘if’ function, or suggest a better way of achieving this?
Thanks in advance
The problem with your current xsl:if condition….
…. is that the first forward slash means it is an absolute path, starting from the root element, so all the xsl:if is saying is whether there is any SiteMapNode, immediately under the siteMap element, that is not an Admin role. This means it will always be true in your case.
You really only want to check the role of the current element
However, there is a tidier way of doing this. Remove the xsl:if condition, and just have a separate template to match the admin role elements, and ignore them.
Here is the full XSLT
When applied to your sample XML, the following is output
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.