Copied to clipboard

Flag this post as spam?

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


  • Tom Hare 49 posts 81 karma points
    Sep 29, 2011 @ 11:36
    Tom Hare
    0

    Sort problem (msxml:node-set)

    I have a list of events that all have a region attached to them (geographical e.g. East of England, London, North west etc). The user can then select a region from a dropdown list and the results will be filtered depending on which region they select. However, obviously, if a region is not selected then all results will be shown.

    I'm requesting the value from the dropdown list, storing this in a variable, then testing this variable (within an <xsl:choose>) to decide if I should be filtering by a region or not.

    <xsl:variable name="region">
        <xsl:if test="umbraco.library:Request('filterEvents') != 0">
            <xsl:value-of select="umbraco.library:Request('filterEvents')" />
        </xsl:if>
    </xsl:variable>
    <xsl:variable name="matchedNodes2">
        <xsl:choose>
            <xsl:when test="string($region) != ''">
                <xsl:copy-of select="$currentPage/descendant::*[@isDoc and local-name()!='EventFolder' and string(eventRegion)=string($region)]" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy-of select="$currentPage/descendant::*[@isDoc and local-name()!='EventFolder']" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <xsl:variable name="matchedNodes" select="msxml:node-set($matchedNodes2)" />

    As you can see, I'm creating an msxml:node-set with the results of the select so that the XML can be traversed later on. At this, point the results could be printed onto screen without any problems.

    However! I'm using Lee's XSLT pagination to provide page numbers but a crucial part of this is causing problems. I believe that it's failing when it gets to the <xsl:sort> because it can't sort the 'copied' msxml node-set for whatever reason (line 3 of the below code being the crucial bit).

    <xsl:if test="$matchedNodes">
        <xsl:apply-templates select="$matchedNodes">
            <xsl:sort select="@createDate" order="descending" data-type="text" />
            <xsl:with-param name="startMatch" select="$startMatch" />
            <xsl:with-param name="endMatch" select="$endMatch" />
        </xsl:apply-templates>
    </xsl:if>

    <xsl:if test="$nodeCount &gt; $resultsPerPage">
        <xsl:call-template name="pagination">
            <xsl:with-param name="page" select="$page" />
            <xsl:with-param name="matchedNodes" select="$matchedNodes" />
        </xsl:call-template>
    </xsl:if>

    Has anyone come across problems sorting msxml:node-set before? Or preferrably a better way of testing the $region variable and selecting the relevant nodes further up...

    Thanks!

  • Lee Kelleher 4026 posts 15836 karma points MVP 13x admin c-trib
    Sep 29, 2011 @ 12:19
    Lee Kelleher
    1

    Hi Tom,

    Not sure what is happening with the sorting for the copied nodeset - it sounds like it should work?

    When I've had to do filtering in the past, I've built up an XPath string and passed it to GetXmlNodeByXPath method:

    <xsl:variable name="xpath">
        <xsl:text>//EventFolder</xsl:text>
        <xsl:if test="normalize-space($region)">
            <xsl:text>[eventRegion = '</xsl:text>
            <xsl:value-of select="$region" />
            <xsl:text>']</xsl:text>
        </xsl:if>
    </xsl:variable>
    <xsl:variable name="matchedNodes" select="umbraco.library:GetXmlNodeByXPath($xpath)" />

    Cheers, Lee.

  • Tom Hare 49 posts 81 karma points
    Sep 29, 2011 @ 13:16
    Tom Hare
    0

    Brilliant! All working smoothly now. Cheers Lee!

    Tom

  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    Sep 29, 2011 @ 20:54
    Chriztian Steinmeier
    1

    Hi Tom,

    Just to chip in on the sort issue: It's most likely related to the anonymous parent "wrapper" that the copied nodes are attached to. So in effect, the sort works - it's just that it's applied to the wrapper instead, which of course there's only one of :-) Furthermore, there's no template for that "element" so a built-in template kicks in and makes sure to continue applying templates, but this time without the sort... this would also mean that the pagination won't kick in - was that what you experienced?

    Anyway, just because there's more than one way to skin a cat (or how does that saying go?) - here's how I'd go about it:

    <xsl:variable name="allNodes" select="$currentPage//*[@isDoc][not(self::EventFolder)]" />
    
    <xsl:variable name="matchedNodesProxy">
        <xsl:choose>
            <xsl:when test="normalize-space($region)">
                <xsl:copy-of select="$allNodes[eventRegion = $region]" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy-of select="$allNodes" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>
    <xsl:variable name="matchedNodes" select="msxml:node-set($matchedNodesProxy)/*" />
    
    <xsl:apply-templates select="$matchedNodes">
        <xsl:sort select="@createDate" order="descending" data-type="text" />
        <xsl:with-param name="startMatch" select="$startMatch" />
        <xsl:with-param name="endMatch" select="$endMatch" />
    </xsl:apply-templates>
    
    <xsl:if test="$nodeCount &gt; $resultsPerPage">
        <xsl:call-template name="pagination">
            <xsl:with-param name="page" select="$page" />
            <xsl:with-param name="matchedNodes" select="$matchedNodes" />
        </xsl:call-template>
    </xsl:if>
    

    /Chriztian

     

  • Tom Hare 49 posts 81 karma points
    Sep 30, 2011 @ 11:17
    Tom Hare
    0

    Thanks for your input Chriztian. I was fairly sure it had something to do with the node set being malformed but it's good to find out exactly what was happening!

    Tom

Please Sign in or register to post replies

Write your reply to:

Draft