Copied to clipboard

Flag this post as spam?

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


  • Claushingebjerg 939 posts 2574 karma points
    Aug 15, 2013 @ 14:21
    Claushingebjerg
    0

    Comparing two sets of nodes and finding the unique nodes

    So i need to list some subnodes from another node.
    The thing is, i only want to list the nodes that are NOT also picked on a MNTP on $currentPage.

    I have a hunch i need to make a two node sets. One set of the subnodes, and one set of the nodes picked with the picker, and then compare these two with "contains()" somehow.

    But im a bit lost as how to get it set up.

    Any help :) ?

     

     

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Aug 15, 2013 @ 14:29
    Chriztian Steinmeier
    100

    Hi Claus,

    Here's a scenario with Categories - you should be able to change what's needed for your own use:

    <xsl:param name="currentPage" />
    <xsl:variable name="siteRoot" select="$currentPage/ancestor-or-self::*[@level = 1]" />
    
    <!-- Grab all the available categories -->
    <xsl:variable name="categories" select="$siteRoot/Categories/Category" />
    
    <xsl:template match="/">
        <!-- Process all categories that haven't been picked in the categoryPicker  -->
        <xsl:apply-templates select="$categories[not(@id = $currentPage/categoryPicker//nodeId)]" />
    </xsl:template>
    
    <!-- Output template -->
    <xsl:template match="Category">
        <p><xsl:value-of select="@nodeName" /></p>
    </xsl:template>
    

    /Chriztian

  • Claushingebjerg 939 posts 2574 karma points
    Aug 15, 2013 @ 15:08
    Claushingebjerg
    0

    Hmmmm as alawys its not quite working out :|

    <xsl:param name="currentPage"/>

    <xsl:variable name="siteRoot" select="umbraco.library:GetXmlNodeById(1075)" />
    <xsl:variable name="categories" select="$currentPage/sekundaartikler/MultiNodePicker" />

    <xsl:template match="/">
    <xsl:apply-templates select="$categories[not(@id = $currentPage/sekundaartikler/MultiNodePicker//nodeId)]" />
    </xsl:template>

    <xsl:template match="Artikel">
    <p><xsl:value-of select="@nodeName" /></p>
    </xsl:template>

    Doing this renders the id's of the nodes picked with the picker...

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Aug 15, 2013 @ 17:39
    Chriztian Steinmeier
    0

    Yeah - you need to point the $categories variable to the actual Artikel nodes, instead of the MultiNodePicker you're currently pointing to.

    /Chriztian

  • Claushingebjerg 939 posts 2574 karma points
    Aug 15, 2013 @ 20:54
    Claushingebjerg
    0

    Awesome, it works! not 100% sure i understand why it can be this easily though :)

    For reference i ended up with:

    <xsl:param name="currentPage"/>
    <xsl:variable name="siteRoot" select="umbraco.library:GetXmlNodeById(1075)" />
    <xsl:variable name="categories" select="$siteRoot/*" />

    <xsl:template match="/">
    <xsl:apply-templates select="$categories[not(@id = $currentPage/sekundaartikler/MultiNodePicker//nodeId)]" />
    </xsl:template>

    <xsl:template match="Artikel">
    <p><xsl:value-of select="@nodeName" /></p>
    </xsl:template>
  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Aug 16, 2013 @ 09:17
    Chriztian Steinmeier
    0

    Hehe :-)

    Well, the main reason is probably the usual for many developers: The fact that XSLT uses sets and is very efficient at manipulating those. If you've never done XSLT before (I know you have, though :-) you'd think you'd need to run through all items, checking the ids etc.

    Here, you have a set of all the possible nodes (the $categories variable) and then you just ask for all of those that doesn't have an @id that's been picked in the MNTP property (sekundaartikler) - and that part works because, again, the $currentPage/sekundaartikler/MultiNodePicker//nodeId selects another set (containing nodeId nodes).

    One tiny nit-pick I have: Unless your Artikel nodes are children of your Home node, you should rename the $siteRoot variable to something better, like $categoryRoot - because, well - just because :-)

    /Chriztian

  • Claushingebjerg 939 posts 2574 karma points
    Aug 16, 2013 @ 12:52
    Claushingebjerg
    0

    Thanks, that makes good sense.

    A little bonus qusetion.

    If i want to list, lets say 8 nodes, ive done the following, but it doesnt really fly, as it takes the position regardless of the nodes we filteret out... So ti doesnt show 8 nodes, but less...

    <xsl:template match="Artikel">
    <xsl:if test="position() &lt; 9">
    <p><xsl:value-of select="@nodeName" /></p>
    </xsl:if> </xsl:template> 

     

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Aug 16, 2013 @ 13:04
    Chriztian Steinmeier
    0

    Hi Claus,

    Yeah, that's the case where you need to use for-each instead :-)

    You can keep the simple Artikel template, here's how:

    <xsl:for-each select="$categories[not(@id = $currentPage/sekundaartikler/MultiNodePicker//nodeId)]">
        <xsl:if test="position() < 9">
            <xsl:apply-templates select="." />
        </xsl:if>
    </xsl:for-each>
    

    If you need to use position within the Artikel content, either move the contents of the template inside the for-each, or pass it along as a separate parameter, like this:

    <xsl:for-each select="$categories[not(@id = $currentPage/sekundaartikler/MultiNodePicker//nodeId)]">
        <xsl:if test="position() &lt; 9">
            <xsl:apply-templates select=".">
                <xsl:with-param name="pos" select="position()" />
            </xsl:apply-templates>
        </xsl:if>
    </xsl:for-each>
    
    <xsl:template match="Artikel">
        <xsl:param name="pos" />
        <p>
            <xsl:value-of select="concat(@nodeName, ' [{$pos}]')" />
        </p>
    </xsl:template>
    

    /Chriztian

  • Claushingebjerg 939 posts 2574 karma points
    Aug 16, 2013 @ 13:58
    Claushingebjerg
    0

    Awesome. We are sooooo close now :).

    But of course i need to add another if statement, which f...s it up again :)

    As im using this macro around the site based on a section selection on the article and section frontpage i need to use only the nodes who actually belong

    Are we looking at adding a <xsl:with param... or am i on the wrong track?

    For now im doing like this, but ágain, it returns less than 8 nodes because of <xsl:if test="contains (sektion, $currentPage/sektion)">

    <xsl:for-each select="$categories[not(@id = $currentPage/sekundaartikler/MultiNodePicker//nodeId)]">
    <xsl:sort select="@createDate" order="descending" />
    <xsl:if test="position() &lt; 9">
    <xsl:if test="contains (sektion, $currentPage/sektion)">
    <xsl:apply-templates select=".">
    <xsl:with-param name="pos" select="position()" />
    </xsl:apply-templates>
    </xsl:if>
    </xsl:if>
    </xsl:for-each>
  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Aug 16, 2013 @ 22:44
    Chriztian Steinmeier
    1

    Alrighty :-)

    Well, you need to filter the nodes before you do the position() check - otherwise you'll end up with the same problem (getting 8 nodes but then filtering one or two of those out because of some condition).

    So you'll need to add the check you're performing to the select you're doing in the for-each, but now it's a little too long so let's split it with a couple of variables:

    <!-- Filter the categories to get rid of those picked in the MNTP -->
    <xsl:variable name="unpicked" select="$categories[not(@id = $currentPage/sekundaartikler/MultiNodePicker//nodeId)]" />
    
    <!-- Take the last 8 of those that match the current pages's "sektion" property -->
    <xsl:for-each select="$unpicked[contains(sektion, $currentPage/sektion)]">
        <xsl:sort select="@createDate" order="descending" />
        <xsl:if test="position() &lt; 9">
            <xsl:apply-templates select=".">
                <xsl:with-param name="pos" select="position()" />
            </xsl:apply-templates>
        </xsl:if>
    </xsl:for-each>
    

    /Chriztian

  • Claushingebjerg 939 posts 2574 karma points
    Aug 21, 2013 @ 08:55
    Claushingebjerg
    0

    Beer on me!

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Aug 21, 2013 @ 09:00
    Chriztian Steinmeier
    0

    I will collect that when we meet again :-)

Please Sign in or register to post replies

Write your reply to:

Draft