Copied to clipboard

Flag this post as spam?

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


  • Giorgos Grispos 145 posts 179 karma points
    Mar 21, 2013 @ 18:23
    Giorgos Grispos
    0

    Preceding sibling for unique nodes

    Hello,

    I need to get only unique nodes one by one. Having the following piece I am getting more than a sinlge node every time I use it, if I try to put position() = 1 or [1] at the end then I always get just the first. Any ideas?

    <xsl:copy-of select="$currentPage/descendant::*[@isDoc] /* [name() = $documentTypeAlias and @parentID = 1067 and string(nodeShowOnHome) = 1 and not(@id = preceding-sibling::Project/@id)]"/>

    Thanks, Giorgos

  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    Mar 21, 2013 @ 22:06
    Chriztian Steinmeier
    0

    Hi Giorgos,

    I don't fully understand what you're trying to do — could you maybe share a little more info?

    The last predicate - "and not(@id = preceding-sibling::Project/@id)" does not make sense to me - ID's are unique, so you can never have a node which has the same @id as another. Are you by any chance looping through a set of nodes, copying specific nodes into a variable? I guess that's where you could run into this...

    Another problem is that these axes (preceding::, preceding-sibling:: etc.) *always* work in "document order", so you can't use them to test against the nodes you've previously copied, if that's what you're doing.

    Let us know a little more of why you need to copy these nodes, and I'm sure we can help.

    If you're able to select all the nodes you need in a single select="...", you don't need to worry about duplicates, because a node can only exist once in a set (using copy-of destroys that), even if you select multiple "almost identical" sets, e.g.:

    <!-- Even though the first will include all the nodes in the second, only one of each will exist in the $nodes variable  -->
    <xsl:variable name="nodes" select="$currentPage//*[@isDoc] | $currentPage/*[@isDoc]" />

     

    /Chriztian

     

  • Giorgos Grispos 145 posts 179 karma points
    Mar 22, 2013 @ 08:51
    Giorgos Grispos
    0

    Hi Chriztian,

    That was a completely wrong approach from my site, you're right I was trying to loop and copy specific nodes into specific position of a cusotm xml. The idea is that I got two different node groups one with videos (@parentID=1066) and one with photos (@parentID=1067). I wanted to make a custom xml with videos and in random position add a photo and then again anag again.

    Here is the correct approach. Any other ideas are welcome.

    Cheers, Giorgos

    <xsl:variable name="nodes">
    <root>
          <xsl:for-each select="$currentPage/ancestor::root//* [@isDoc] /* [name() = $documentTypeAlias and @parentID = 1066 and string(nodeShowOnHome) = 1]">
            <xsl:copy-of select="."/>
            <xsl:if test="position() mod $RandomPhoto=0">
       <xsl:variable name="index" select="number(position() div $RandomPhoto)"/>
              <xsl:copy-of select="$currentPage/descendant::*[@isDoc] /* [name() = $documentTypeAlias and @parentID = 1067 and string(nodeShowOnHome) = 1][$index]"/>
            </xsl:if>            
          </xsl:for-each>
        </root>
      </xsl:variable>

  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    Mar 22, 2013 @ 09:21
    Chriztian Steinmeier
    100

    Hi Giorgos,

    Great - that makes sense! Usually when doing something like that, I just create a "pointer" node in the collection variable, which I can then use to find the original node — that way the processor won't have to copy the full subtree etc. — here's my approach to it; feel free to ask away about it:

    <!-- Grab the container nodes -->
    <xsl:variable name="videoRoot" select="umbraco.library:GetXmlNodeById(1066)" />
    <xsl:variable name="photoRoot" select="umbraco.library:GetXmlNodeById(1067)" />
    
    <!-- Grab the relevant children -->
    <xsl:variable name="videos" select="$videoRoot/*[name() = $documentTypeAlias][nodeShowOnHome = 1]" />
    <xsl:variable name="photos" select="$photoRoot/*[name() = $documentTypeAlias][nodeShowOnHome = 1]" />
    
    <!-- Build a custom set of pointers -->
    <xsl:variable name="nodesProxy">
        <root>
            <xsl:for-each select="$videos">
                <!-- Store a reference to the video node -->
                <videoRef id="{@id}" />
                <xsl:if test="position() mod $RandomPhoto = 0">
                    <xsl:variable name="index" select="position() div $RandomPhoto" />
                    <!-- Store a reference to the photo node -->
                    <photoRef id="{$photos[$index]/@id}" />
                </xsl:if>
            </xsl:for-each>
        </root>
    </xsl:variable>
    <xsl:variable name="nodes" select="msxml:node-set($nodesProxy)/root/*" />
    
    <xsl:template match="/">
        <div>
            <!-- Process the videoRef + photoRef nodes -->
            <xsl:apply-templates select="$nodes" />
        </div>
    </xsl:template>
    
    <xsl:template match="videoRef | photoRef">
        <!-- Find the real node (it must be in the combined set of videos and photos, since that is where we took it from) -->
        <xsl:variable name="node" select="($videos | $photos)[@id = current()/@id]" />
        <p>
            <!-- Output stuff from the node -->
            <xsl:value-of select="$node/@nodeName" />
        </p>
    </xsl:template>
    

    /Chriztian 

  • Giorgos Grispos 145 posts 179 karma points
    Mar 22, 2013 @ 09:26
    Giorgos Grispos
    0

    That's great approach, so do you think that can be fatser, right?

    Thanks Chritzian!

  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    Mar 22, 2013 @ 09:57
    Chriztian Steinmeier
    0

    Oh yes, I think it is :-)

    Just doing the "container" variables will greatly improve the performance of the lookups, because you're no longer going up & down the tree in every iteration.

    Not copying entire nodes is guaranteed to speed things up — if not, beer's on me :-)

    /Chriztian

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies