Copied to clipboard

Flag this post as spam?

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


  • David Cardine 7 posts 27 karma points
    Feb 22, 2011 @ 16:09
    David Cardine
    0

    xpath multiple query intersection or smart query

    I've been working on this one for a while, and have finally given up.

    I have currently 2 different filters i'd like to apply to my xpath query. one is a time based one (month & year), and another is a category query. My goal is to create either different queries and intersect them to get common elements, or to build a smart query (not preferred) which will only set my attribute filters if they are set.

    I've been messing around with some examples i've found using set:intersection and $n1[count(.|$n2) = count($n2)] and i'm either doing it wrong (most likely) or it's not working.

    here's what i was doing regarding the intersection

    <xsl:variable
     name="month" select="/macro/month" />
    <xsl:variable name="year" select="/macro/year" />
    <xsl:variable name="categoryId" select="/macro/categoryId" />

    <xsl:variable name="timeQuery">
      <xsl:choose>
        <xsl:when test="$year!='' and $month!=''">
            <xsl:copy-of select="$currentPage/Posts/Year[@nodeName=$year]/Month[@nodeName=$month]/*"/>      
        </xsl:when>
        <xsl:when test="$year!=''">
            <xsl:copy-of select="$currentPage/Posts/Year[@nodeName=$year]/Month/*"/>
        </xsl:when>
        <xsl:when test="$month!=''">
            <xsl:copy-of select="$currentPage/Posts/Year/Month[@nodeName=$month]/*"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:copy-of select="$currentPage/Posts/Year/Month/*"/>
        </xsl:otherwise>
      </xsl:choose>    
    </xsl:variable>
        
    <xsl:variable name="categoryQuery">  
        <xsl:if test="$categoryId!=''">
          <xsl:copy-of select="$currentPage/Posts/Year/Month/*[category[text()=$categoryId]]"/>      
        </xsl:if>  
    </xsl:variable>
        
    <xsl:variable name="intersection" select="msxml:node-set($timeQuery)[count(.|msxml:node-set($categoryQuery)) = count(msxml:node-set($categoryQuery))]" />
    <xsl:template
     match="/">   
      <ul>
        <xsl:for-each select="$intersection">.....

     

    i took a quick stab at a smart query, using if else conditionals (which i found was in xpath 2.0), but i guess i was doing it wrong, as i continued to get errors on the if() being invalid.

    <xsl:variable name="query" select="$currentPage/Posts/Year if($year!='') then([@nodeName=$year])/Month if($month!='') then([@nodeName=$month])/* if($categoryId!='') then([category[text()=$categoryId]])"/> 

     

    Thanks for any input!

  • Rob Watkins 369 posts 701 karma points
    Feb 22, 2011 @ 17:35
    Rob Watkins
    0

    .NET does not support XPath 2.

    Would this post help with your intersections? http://www.biglist.com/lists/xsl-list/archives/200105/msg00627.html

    Something to do with the way the nodes are compared?

  • David Cardine 7 posts 27 karma points
    Feb 22, 2011 @ 19:35
    David Cardine
    0

    well ain't that just a kick in the junk.

    Thanks!

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Feb 22, 2011 @ 23:37
    Chriztian Steinmeier
    0

    Hi David,

    Actually - the reason the intersection stuff doesn't work is because you're using copy-of and node-set() - the intersect "trick" works because a node can not exist twice in the same set (unless it was cloned, which copy-of does...) - maybe you pulled the trick from a sample that used the key() function? 'coz that works, I can tell you - BUT: using keys in Umbraco is a little bit tricky because the key() function can only find nodes in the document that contains the current node (not the same as $currentPage) - when a macro runs, the XML document it processes is a tiny <macro> document, which doesn't contain much, and you have to use a for-each on $currentPage, or apply-templates to some node before using the key()...

    You can however build a dynamic query and the use the GetXmlNodeByXPath() function - check the solution here for a way to do something like that.

    /Chriztian

     

Please Sign in or register to post replies

Write your reply to:

Draft