Dividing large lists of items into pages often is necessary. Here is one way to approach it, passing the page/group number as part of the query string. 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:Stylesheet [
<!ENTITY nbsp "&#x00A0;">
<xsl:stylesheet xmlns:xsl=
    version="1.0" exclude-result-prefixes="msxml umbraco.library">

  <xsl:output method="xml" omit-xml-declaration="yes"/>
  <xsl:param name="currentPage"/>

  <!-- Parameters
    RootNode: root of content nodes
    numberOfItems: number of items on page
    GroupNo: current group displayed - from querystring
  <xsl:variable name="RootNode" select="/macro/rootNode"/>
  <xsl:variable name="numberOfItems" select="/macro/numberOfItems"/>
  <xsl:variable name="GroupNo">

      <xsl:when test="umbraco.library:RequestQueryString('GroupNo') &lt;= 0 or
                               string(umbraco.library:RequestQueryString('GroupNo')) = '' or
                               string(umbraco.library:RequestQueryString('GroupNo')) = 'NaN'">0</xsl:when>
        <xsl:value-of select="umbraco.library:RequestQueryString('GroupNo')"/>

  <!-- Main code -->
  <xsl:template match="/">
    <!-- Iterate through all item nodes -->
    <xsl:for-each select="umbraco.library:GetXmlNodeById($RootNode)/descendant::node">
      <!-- Apply some sorting -->
      <xsl:sort select="@createDate" order="descending"/>
      <!-- Check if item node us in the right group interval -->
      <xsl:if test="(position() &lt;= (1+$GroupNo)*$numberOfItems) and
                         (position() &gt;= (($GroupNo))*$numberOfItems)">
        <!-- Yep - show the item, or whatever needed -->

    <!-- Call template to show groups/pages -->
    <xsl:call-template name="DisplayGroupLinks">
      <xsl:with-param name="ShowGroupNo" select="0"/>
      <xsl:with-param name="MaxGroupNo"

                     div $numberOfItems"/>
      <xsl:with-param name="CurrentGroupNo" select="$GroupNo"/>

  <!-- Show groups template -->
  <xsl:template name="DisplayGroupLinks">
    <xsl:param name="ShowGroupNo" select="0"/>
    <xsl:param name="MaxGroupNo" select="0"/>
    <xsl:param name="CurrentGroupNo" select="0"/>
    <xsl:if test="$ShowGroupNo &lt;= $MaxGroupNo">
        <!-- Is this the current group? -->
        <xsl:when test="$ShowGroupNo = $CurrentGroupNo">
          <span class="GroupLinks">
            <xsl:value-of select="1+$ShowGroupNo"/>
          <!-- Nope, this is a group to link to -->
          <a href="?GroupNo={$ShowGroupNo}">
            <span class="GroupLinks">
              <xsl:value-of select="1+$ShowGroupNo"/>

      <!-- Continue recursively for all groups -->
      <xsl:call-template name="DisplayGroupLinks">
        <xsl:with-param name="ShowGroupNo" select="$ShowGroupNo + 1"/>
        <xsl:with-param name="MaxGroupNo" select="$MaxGroupNo"/>
        <xsl:with-param name="CurrentGroupNo" select="$CurrentGroupNo"/>




9. juni 2009:

gr8 help for new comers

Commented by: dilip

24. februar 2010:

The GroupNo can be passed as part of the query string like this: If you do not specify any GroupNo parameter to your url it will default to zero (line 26 in the source above).

Commented by: Tommy