[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: AW: Selection of every second node

Subject: Re: AW: Selection of every second node
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Tue, 21 Aug 2001 14:56:43 +0100
xsl boolean odd numbers count
Hi Conny,

> <xsl:template match="another">
>   <li>
>     <xsl:if test="boolean(parent::node()[(position() mod 2) = 0])">
>       <xsl:attribute name="type">disc</xsl:attribute>
>     </xsl:if>
>     <xsl:value-of select="." />
>   </li>
> </xsl:template>

When you use the position() function in a predicate, you're testing
the position of each of the nodes that are selected by the step
amongst the other nodes in the step. In:

  parent::node()[(position() mod 2) = 0]

you're selecting the parent node of the another element. There can
only be one parent node of any element, so the node set gathered by
the step only has one node in it. Then filtering this node set (which
only contains one node) to get only those whose position mod 2 is
equal to 0. There are no such nodes in the node set, so the location
path returns an empty node set, and the test evaluates as false
(there's no need to use boolean() there, by the way - the contents of
a test attribute are automatically converted to boolean values).

You want to test the position of the current node's parent node
amongst its siblings. There are a couple of ways you could do that.

First, you could use a location path to collect the preceding siblings
of the another element's parent node:

  parent::node()/preceding-sibling::node

(or ../preceding-sibling::node)

Count the number of nodes that gives you - if it's odd then the node
element is an even node, otherwise it's odd:

  <xsl:if test="(count(../preceding-sibling::node) mod 2) = 1">
    <xsl:attribute name="type">disc</xsl:attribute>
  </xsl:if>

Or just:

  <xsl:if test="count(../preceding-sibling::node) mod 2">
    <xsl:attribute name="type">disc</xsl:attribute>
  </xsl:if>

A second approach is to apply templates to the parent node element in
'typeAttribute' mode:

  <xsl:apply-templates select=".." mode="typeAttribute" />

and then have two templates in typeAttribute mode that match nodes in
different positions. One to match odd node elements, which does
nothing:

<xsl:template match="node[(position() mod 2) = 1]"
              mode="typeAttribute" />

and another to match even node elements, which adds the attribute:

<xsl:template match="node[(position() mod 2) = 0]"
              mode="typeAttribute">
  <xsl:attribute name="type">disc</xsl:attribute>
</xsl:template>

If you test the position of a node in a match pattern, its position is
assessed within the set of its similar siblings.

I hope that helps,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.