Copied to clipboard

Flag this post as spam?

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


  • Phil Crowe 192 posts 256 karma points
    Jan 20, 2011 @ 14:49
    Phil Crowe
    0

    using c# random method really slow in xslt

    Im having problems trying to select a radom node from a list of nodes in my xslt:

    <?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" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets"

    exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets myfunctionlib"

     

      xmlns:myfunctionlib="urn:myfunctionlib"

      xmlns:PS.Helpers="urn:PS.Helpers"

      >

     

     

    <msxml:script implements-prefix="myfunctionlib" language="C#" >

     

    <![CDATA[

    Random r = new Random();

     

    public int RandomPos(int max) {

        return r.Next(max);

    }

    ]]>

    </msxml:script>

     

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

     

    <xsl:param name="currentPage"/>

    <xsl:variable name="source" select="/macro/source"/>

    <xsl:variable name="maxresults" select="/macro/MaxResults" />

     

    <xsl:template match="/">

     

     

     

      <img src="/images/my-collection/black-up.jpg" id="mycollup" />

      <ul>

     

     

        <xsl:variable name="selectsourcenode" select="umbraco.library:GetXmlNodeById($source)" />

        <xsl:call-template name="displayrow">

        <xsl:with-param name="getNode" select="$selectsourcenode" />

        <xsl:with-param name="counter" select="1" />

        <xsl:with-param name="maxrows" select="count($selectsourcenode//TextImageData)" />

        </xsl:call-template>

      </ul>

      <img src="/images/my-collection/black-down.jpg" id="mycolldown" />

     

    </xsl:template>

     

        <xsl:template name="displayrow">

          <xsl:param name="counter" />

          <xsl:param name="maxrows" />

     <xsl:param name="getNode" />

          <xsl:variable name="smallcase" select="'abcdefghijklmnopqrstuvwxyz'" />

          <xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />

     

          <xsl:variable name="ranNodeNum" select="myfunctionlib:RandomPos($maxrows)" />

            <xsl:variable name="nonrandomnode" select="$getNode//TextImageData[position()=$ranNodeNum]"/>

    <xsl:variable name="randomnode" select="$nonrandomnode [not(@id=preceding-sibling::node/@id)]"/>

    <xsl:value-of select="$maxrows"/>

     

          <xsl:choose>

              <xsl:when test="$randomnode/member != ''">

                <li class="licomment">

     

                <xsl:variable name="mxml" select="umbraco.library:GetMember($randomnode/member)" />

                <div class="myCollectionLatest" id="mycollectioncomment{$counter}">

                  <div style="float:left;">

                    <div class="colltoppic">

                      <a href="/my-collection.aspx?memberId={$mxml/*/@id}">

                <img src="{$mxml/node/profilePicture}" width="74" height="74" onerror="ImgError(this);" />

     

                      </a>

                    </div>

                    <xsl:choose>

                      <xsl:when test="string-length($randomnode/image) &gt; 1">

                        <div class="commentimage ie6commentimageifx" style="clear:both;">

                          <img src="{$randomnode/image}"  width="74" height="74" />

                        </div>

                      </xsl:when>

                      <xsl:otherwise>

                        <div class="commentimage ie6commentimageifx" style="clear:both;">

                          <img src="/images/my-collection/c2k-tip-placeholder.jpg"  width="74" height="74" />

                        </div>

                      </xsl:otherwise>

                    </xsl:choose>

                    <div style="float:left; position:absolute; margin-left:83px; margin-top:-84px; width:160px;" class="mycolllatestlinks">

     

                        <b>

                          <xsl:variable name="parent" select="$randomnode/@parentID">

     

                            </xsl:variable>

                          <!--  <xsl:variable name="granparent" select="$randomnode/../../@id" /> -->

    <!--<xsl:choose>

    this is the check to see if a gran-parent exsists, currently some nodes reference an incorrect parent id-->

    <!-- <xsl:when test="contains($granparent/@path, '-1')">

    <a href="/my-collection.aspx?memberId={$mxml/*/@id}" class="usernamelinkdiv">

    <xsl:value-of select="translate($mxml/node/screenName, $smallcase, $uppercase)"/>

    </a> SAID 

    </xsl:when>

    <xsl:otherwise> -->

     

    <xsl:choose>

    <xsl:when test="string-length($randomnode/../../@nodeName) &gt; 0">

    <a href="/my-collection.aspx?memberId={$mxml/*/@id}" class="usernamelinkdiv">

    <xsl:value-of select="translate($mxml/node/screenName, $smallcase, $uppercase)"/>

    </a> SAID ABOUT

     

    <span class="pinkTxt">

     

    <br />

     

    <xsl:choose>

    <xsl:when test="name($randomnode/../../.) = 'ProductCategory'">

    <a href="{umbraco.library:NiceUrl($randomnode/../../@id)}?categoryId=1">

    <xsl:value-of select="translate($randomnode/../../@nodeName, $smallcase, $uppercase)"/>

    </a>

    </xsl:when>

    <xsl:when test="name($randomnode/../../.) = 'ProductSubCategory'">

    <a href="{umbraco.library:NiceUrl($randomnode/../../@id)}?searchingForProduct=1">

    <xsl:value-of select="translate($randomnode/../../@nodeName, $smallcase, $uppercase)"/>

    </a>

    </xsl:when>

    <xsl:otherwise>

    <a href="{umbraco.library:NiceUrl($randomnode/../../@id)}">

    <xsl:value-of select="translate($randomnode/../../@nodeName, $smallcase, $uppercase)"/>

    </a>

    </xsl:otherwise>

     

    </xsl:choose> 

     

    </span>

    </xsl:when>

     

    <xsl:otherwise>

    <a href="/my-collection.aspx?memberId={$mxml/*/@id}">

    <xsl:value-of select="translate($mxml/node/screenName, $smallcase, $uppercase)"/>

    </a> SAID

    </xsl:otherwise>

    </xsl:choose>

    <!--add this because some comments didnt seem to have a product against them-->

    <!-- </xsl:otherwise>

    </xsl:choose>-->

                        </b>

     

                      <p>

                      <xsl:value-of select="substring(umbraco.library:StripHtml($randomnode/text),1,120)" />...

                    </p>

     

                    </div>

                    <div class="randomCommentsSeeMore">

                      <span class="pinkTxt">

                        <a href="/my-collection.aspx?memberId={$mxml/*/@id}">

                          See more <img src="/images/navControls/more-arrow.jpg" alt="see more" />

                        </a>

                    </span>

                    </div>

                  </div>

     

                </div>

     

     

              </li>

                <xsl:if test="$counter &lt; $maxresults">

     

                  <xsl:call-template name="displayrow">

     <xsl:with-param name="getNode" select="$getNode" />

                    <xsl:with-param name="counter" select="$counter + 1" />

                    <xsl:with-param name="maxrows" select="$maxrows" />

                  </xsl:call-template>

     

                </xsl:if>

           </xsl:when>

          <xsl:when test="$randomnode/member = ''">

            <xsl:if test="$counter &lt; $maxresults">

     

              <xsl:call-template name="displayrow">

     <xsl:with-param name="getNode" select="$getNode" />

                <xsl:with-param name="counter" select="$counter" />

                <xsl:with-param name="maxrows" select="$maxrows" />

              </xsl:call-template>

     

            </xsl:if>

          </xsl:when>

          <xsl:otherwise>

            <xsl:if test="$counter &lt; $maxresults">

     

              <xsl:call-template name="displayrow">

     <xsl:with-param name="getNode" select="$getNode" />

                <xsl:with-param name="counter" select="$counter" />

                <xsl:with-param name="maxrows" select="$maxrows" />

              </xsl:call-template>

     

            </xsl:if>        

          </xsl:otherwise>

          </xsl:choose>

        </xsl:template>

     

    </xsl:stylesheet>

     

    im trying to get a scrollable list of random items. maxrows currently equals 541 rows and the maxresults is 10. if i change the randomPos method at the top of the xslt to return a low number like 

    return r.Next(12) + 1; instead of the maxrow parameter its alot quicker, i dont get it though surely this is just going to just spit out 10 random numbers, there shouldnt be any calculations that would slow it down. any ideas?

  • Jan Skovgaard 11280 posts 23678 karma points MVP 11x admin c-trib
    Jan 20, 2011 @ 15:14
    Jan Skovgaard
    0

    Hi Phil

    I must admit that I have not looked your code through very thoroughly since the formatting is not very good (I blame the RTE for this - not you :)).

    However it seems like you're writing some C# of your own, correct?

    I think that instead you should perhaps try and follow this guide to get random nodes: http://our.umbraco.org/wiki/reference/xslt/snippets/getting-a-series-of-unique-random-numbers

    But it's not a good practive to use inline C# - So if you have the skills you will probably achieve better performance creating a XSLT extension to give you the randomness you need. However the guide I have linked you to works like a charm and I have not experienced any bad performance on those sites I've used it on so far.

    Hope this helps.

    /Jan

  • Phil Crowe 192 posts 256 karma points
    Jan 20, 2011 @ 18:20
    Phil Crowe
    0

    thanks jan, tried your suggestion but got the same result. problem seems to be this line:

    <xsl:variable name="nonrandomnode" select="$getNode//TextImageData[position()=$ranNodeNum]"/> 

    if i try and get a node with a position higher than 50 it all goes very slow, actually i havent yet been able to load a page with a node higher 50. 

  • Phil Crowe 192 posts 256 karma points
    Jan 20, 2011 @ 19:08
    Phil Crowe
    0

    im getting even more confused now. 

    <xsl:for-each select="$getNode//TextImageData[@isDoc and position() = 66]">

    node here

    </xsl:for-each>

     

    this shows me there is a node at position 66, but then

    <xsl:for-each select="$getNode//TextImageData[@isDoc and position() = 67]">

    node here

    </xsl:for-each>
    shows me nothing! like theres no node at this position or any position after. Any ideas????

  • Phil Crowe 192 posts 256 karma points
    Jan 27, 2011 @ 15:31
    Phil Crowe
    0

    i didnt get a solution out of this so thought i'd try and bring it back up. basically when reading the xml the 'for-each' gets 67 nodes down the list ok but once it gets to 68 nodes or further, it just gives up. 

     

    ????

Please Sign in or register to post replies

Write your reply to:

Draft