RE: [xsl] mod position() tests positive all of the time

Subject: RE: [xsl] mod position() tests positive all of the time
From: cknell@xxxxxxxxxx
Date: Sat, 30 Dec 2006 08:40:53 -0500
You haven't been able to find the solution because you are too unfamiliar with the subject to formulate the question suitably.

You are trying too hard to force the input through the stylesheet instead of letting the stylesheet do the work for you. Your stylesheet is based on what in XSLT is called the "push" model of processing.

Once you get comfortable with XSLT, you will find the "pull" model to be more effective in most cases. You didn't show us an example of your input document, but from the XSLT, I inferred it to be something like this:

<doc>
  <insightResponse>
    <searchResponse>
      <collectionResultSet>
        <object>
          <thumbnail URL="">
            <label />
          </thumbnail>
        </object>
      </collectionResultSet>
    </searchResponse>
  </insightResponse>
  
  ... more insightResponse elements here ..
</doc>

Once you get into an <xsl:for-each>, the "context" node is the only node, so position() mod 5 will always yield "1" as the result. Try this stylesheet. It will probably give the result you are looking for.

<?xml version="1.0" encoding="iso-8859-1"?>
  <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
  <xsl:output method="html" encoding="iso-8859-1"/>

<xsl:template match="/">
    <xsl:apply-templates />
  </xsl:template>

<xsl:template match="insightResponse">
    <xsl:apply-templates />
  </xsl:template>

<xsl:template match="searchResponse">
    <xsl:apply-templates />
  </xsl:template>

<xsl:template match="collectionResultSet">
    <xsl:apply-templates />
  </xsl:template>

<xsl:template match="object">
    <xsl:apply-templates />
  </xsl:template>

<xsl:template match="thumbnail">
    <xsl:choose>
      <xsl:when test="position() mod 5 = 1">
        <tr>
          <td align="center">
            <img src="{@URL}" />
            <xsl:apply-templates />
          </td>
        </tr>
      </xsl:when>
      <xsl:otherwise>
        <td align="center">
          <img src="{@URL}" />
          <xsl:apply-templates />
        </td>
      </xsl:otherwise>
    <xsl:choose>
  </xsl:template>
  
<xsl:template match="label">
    <xsl:value-of select="." />
  </xsl:template>
</xsl:stylesheet>
-- 
Charles Knell
cknell@xxxxxxxxxx - email



-----Original Message-----
From:     Allen Jones <jonesa@xxxxxxxxxxxxx>
Sent:     Sat, 30 Dec 2006 07:06:32 -0500
To:       <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
Subject:  [xsl] mod position() tests positive all of the time

I am new to the list, but I have checked the archive for this particular
problem and I haven't been able to find a solution to this.

I am using the following stylesheet and everytime it tests for position,
the results always print the <tr> (rather than printing every 5th
element). Since I am new to XSLT, I know it is probably in the code. 
Any help would be a lesson.

Allen Jones

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:output method="html" encoding="iso-8859-1"/>
<xsl:template match="/">
<html>
      <body >
<xsl:call-template name="results"/>
      </body>
    </html>
</xsl:template>

<xsl:template name="results">
<table>
<xsl:for-each
select="insightResponse/searchResponse/collectionResultSet/object/thumbnail[position()
mod 5 = 1]">
<tr>
<xsl:apply-templates select=". | following-sibling::thumbnail[position()
< 5]" />
</tr>
</xsl:for-each>
</table>
</xsl:template>

<xsl:template match="thumbnail">
<td align="center"><img src="{@URL}" /><br />
<xsl:for-each select="label"><xsl:value-of select="."/><br
/></xsl:for-each>
</td>
</xsl:template> 
</xsl:stylesheet>



Allen Jones
Director - Digital Library Programs
University Library - New School
55 West13th Street, room 905
New York, NY 10011
(voice) 212.229.5309 x4502
(fax) 212.675.7361

Current Thread