views:

34

answers:

1

Hi,

I'm trying to retreive the previous node in a for-each using the preceding-sibling axis, a filter and an indexer to find it.

The problem is, I only want the first item that matches the XPath in the selector however, I seem unable to apply both the filter and the indexer. The indexer seems to override the filter so I always get the first preceding sibling rather than the first one matching the filter.

I've tried putting this in a variable inside the foreach but since the variable cannot be changed the nodeset is always the second item's preceding sibling's values.

Here's the relevant code (chopped out as much noise as possible). Apologies for the umbraco noise (the XSLT is for generating some fairly complicated markup for a subnav which I can't change easily).

<xsl:for-each select="$currentPage/ancestor-or-self::node[(@nodeTypeAlias='Discover' or @nodeTypeAlias='CampaignHome') and data[@alias='umbracoNaviHide'] != 1]/child::node[(@nodeTypeAlias='Discover' or @nodeTypeAlias='CampaignHome') and data[@alias='umbracoNaviHide'] != 1]">  

   <!--This variable is always set to the second item's preceding sibling-->
   <xsl:variable name="precedingItem" select="preceding-sibling::node[data[@alias='umbracoNaviHide' != 1]]" />

   <!--This variable always contains the second item even if /data/@alias='umbracoNaviHide' = 1 -->
   <xsl:variable name="predingItemWithIndexer" select="preceding-sibling::node[data[@alias='umbracoNaviHide' != 1]][1]" /> 

     <!--  this always prints out the id of the first item -->
     <xsl:value-of select="position()" /> <xsl:value-of select="$precedingItem[1]/@id" />
</xsl:foreach>

I would use the second selector inline but because the indexer filter is overriding the other filter it doesn't give the correct values when umbracoNaviHide = 1.

+1  A: 
preceding-sibling::node[data[@alias='umbracoNaviHide' != 1]]

This means: select all the preceding sibling node elements having at least one child data element without an alias attribute or with an alias attribute not equal to "umbracoNaviHide"

EDIT: This is the correct XPath for this:

I wanted the first preceding node element which contains a data element that has an attribute alias called umbracoNaviHide which does not contain the value 1.

preceding-sibling::node[data[@alias='umbracoNaviHide']!=1][1]
Alejandro
I don't want the second preceding element I wanted the first preceding node element which contains a data element that has an attribute alias called umbracoNaviHide which does not contain the value 1.However, you've pointed out that my filter is incorrect thanks! That solved it. I've editted your answer to reflect what I actually wanted.
Rob Stevenson-Leggett