Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Scott 69 posts 146 karma points
    Mar 07, 2012 @ 22:34
    Scott
    0

    Comparing two lists in xslt

    We are currently displaying our naviagtion menu on our website from an XSLT that is retrieving nodes from the content tree under a certain node id. I have been attempting to put some security around which links are shown based on some user groups set in the Asp.Net session. For each content node that is showing as a link, we have a list of checkboxs defined in the document type, that relate to security groups the user might be in, and we only select the checkboxes for the users that should see the link/page. My hope is, using the xslt that already exists, if the user is in one of the groups checked when defining the link/page in the content tree , the link will show for them. So currently we have an xslt:for each that is grabbing each node > a certain id. Then I was attempting to nest two xslt: for-eachs, the outer iterating through the lists of groups the user is in (pulled from asp session) and the inner a list of which those groups has been selected from my custom check box. In my xslt  I'm using umbraco.libary:split which is going to give me two xml lists each of which are going to contain basically the following data:

    Asp session value, UserGroup1,UserGroup2,UserGroup3

    Values checked in checkbox for this page: UserGroup1,UserGroup3

    So in my inner loop I compare my outer loop value to my inner loop value, and if they're the same, I show the user the link to the page. But if you see my example of data, the user is in both UserGroup1 and UserGroup3, and the page has both UserGroup1 and UserGroup3 boxes checked, so the user is going to see the same link twice. So I very quickly toyed with the idea of setting a flag in my inner loop and then checking it after my outer loop was done. Cant do that because of scope.

    So, if I haven't totally confused you...how do I do this. I've seen examples of doing away with foreach and using recursive templates. That just made my head hurt.

     

  • Gerard 20 posts 77 karma points
    Mar 08, 2012 @ 23:29
    Gerard
    0

    Scooter,

    Maybe a weird suggestion:

    Can't you use one splitted for-each loop (for the checkboxes in the page) and compare the values with the ASP session value with XSLT "contains (string, string)"?

    In that case you will check if the name of the Checkbox to check (for example "UserGroup1") is in the concatenated checkbox-names from the sessionvalue ("UserGroup1,UserGroup2,UserGroup3"). Maybe not very nice and robust but might work.

    Here's an example (cut and paste to Umbraco and play with the values)

     <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
    <xsl:stylesheet 
      version="1.0" 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
      xmlns:msxml="urn:schemas-microsoft-com:xslt"
      xmlns:umbraco.library="urn:umbraco.library" 
      exclude-result-prefixes="msxml umbraco.library">

    <xsl:output method="xml" omit-xml-declaration="yes"/>

    <xsl:template match="/">

      <!-- Example 1: User has sufficient rights -->
      
      <xsl:variable name="UserRights1" select="'UserGroup1,UserGroup2,UserGroup3'"/>
      <xsl:variable name="PageRights1" select="'UserGroup1,UserGroup3'"/>

      <xsl:variable name="PageRightsXml1" select="umbraco.library:Split($PageRights1,',')"/>
      <xsl:variable name="MatchCount1" select="count($PageRightsXml1//value[contains($UserRights1,.)])"/>
      <xsl:if test="$MatchCount1 &gt; 0">
        <p>Example 1: One of the UserRights is matching the PageRights</p>
      </xsl:if>

      <!-- Example 2: User has insufficient rights -->
      
      <xsl:variable name="UserRights2" select="'UserGroup1,UserGroup2,UserGroup3'"/>
      <xsl:variable name="PageRights2" select="'UserGroup6,UserGroup7'"/>

      <xsl:variable name="PageRightsXml2" select="umbraco.library:Split($PageRights2,',')"/>
      <xsl:variable name="MatchCount2" select="count($PageRightsXml2//value[contains($UserRights2,.)])"/>
      <xsl:if test="$MatchCount2 &gt; 0">
        <p>Example 2: One of the UserRights is matching the PageRights</p> <!-- this line won't show up, unless you match one of the rights -->
      </xsl:if>
      
      
    </xsl:template>

    </xsl:stylesheet>
  • Scott 69 posts 146 karma points
    Mar 09, 2012 @ 15:48
    Scott
    0

    Holy cow can it be that easy?

    My concern is what if I run into the following 

    I'm in only one user group: 'IMNOTAUSER"

    but my Page rights might be "USER"

    Is it going to find "USER" inside of "IMNOTAUSER" and flag it as matched ?

    It probably wont be an issue for ME specifically because any situation we have that might be similar to this is where a more general group name might be "User" and then its broken down more granular i.e "UserThatCanDeleteRootOfC". So the pagerights would be for the most granular group. But I want to know where my pitfalls might be

    But yeah, I think this is it. Thanks!

  • Gerard 20 posts 77 karma points
    Mar 09, 2012 @ 21:46
    Gerard
    0

    Yes, it wil find USER in IMNOTAUSER. And yes, you're right, this is not the most preferred solution, but i thought it would bring you some new inspiration to find a solution.

    Have you thought about writing a few lines of C# code, compile it and add it to Umbraco?
    With this, you can extend your XSLT with complex functions. As a nice side effect, it will make your XSLT mean, clean and readable.

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 8x admin c-trib
    Mar 11, 2012 @ 16:22
    Chriztian Steinmeier
    0

    Hi Scooter,

    To get around the problem with USER inside IAMNOTAUSER is not hard to fix - instead of looking for "USER", you look for ",USER," and put a comma on each side of the string you're looking inside of, e.g.: look for ",USER," inside ",ADMINUSER,USERMAN,STARUSER," etc.

    /Chriztian

Please Sign in or register to post replies

Write your reply to:

Draft