Monday, January 25, 2010

When you have to display a large number of records, the common practice is to use data paging so the information can be presented in a more user-friendly manner. There are many solutions one can use to implement such a system, and each of them has its own advantages and disadvantages. One of the excellent ways of implementing this solution is using XML and XSL. In this article, I show you how implement this functionality in XSLT. Let's start.

There is XML data below:

<?xml version="1.0" encoding="ISO-8859-1"?>
<data>
<xdata>
Any data
</xdata>
<total_results count="105"/>
<displayCount>20</displayCount>
<pageNumber>1</pageNumber>
</data>

To implement paging for the above situation, we need to be able to pass parameters to the stylesheet, and these parameters can be used to specify information such as the number of records to be displayed, the page number to be displayed, as well as the total number of records. Accomplishing this requires the following two steps.
* Declaring parameters in the XSLT stylesheet
* Supplying parameters to the stylesheet

For this example, let us create a new XSLT stylesheet named paging.xsl and the code for the XSLT stylesheet looks like the following.

<xsl:template name="Page">
<xsl:param name="pCurrentPageNumber" select="pageNumber"/>
<xsl:param name="pRecordsPerPage" select="displayCount"/>
<xsl:param name="pPecordCount" select="total_results/@count"/>
<xsl:param name="pNextPageNumber"/>
<xsl:choose>
  <xsl:when test="$pCurrentPageNumber=$pNextPageNumber">
   <li>
    <a class="act" href="#">
     <xsl:value-of select="$pNextPageNumber"/>
    </a>
   </li>
  </xsl:when>
  <xsl:when test="((number($pNextPageNumber)-1)*number($pRecordsPerPage)) <= number($pPecordCount)">
   <li>
    <a>
     <xsl:attribute name="href">
      <xsl:value-of select="concat('?use_jump=',$pCurrentPageNumber,'&jump_first_car_F=',1+((number($pNextPageNumber)-1) * $pRecordsPerPage),'&current_page_this_search_F=',$pNextPageNumber)"/>
     </xsl:attribute>
     <xsl:value-of select="$pNextPageNumber"/>
    </a>
   </li>
  </xsl:when>
</xsl:choose>
</xsl:template>

<xsl:template name="for.loop">
<xsl:param name="i"/>
<xsl:param name="count"/>
<xsl:param name="currentPage"/>

<xsl:if test="$i <= $count">
  <xsl:call-template name="Page">
   <xsl:with-param name="pNextPageNumber" select="$i"/>
  </xsl:call-template>
  <xsl:call-template name="for.loop">
   <xsl:with-param name="i" select="$i+1"/>
   <xsl:with-param name="count" select="$count"/>
   <xsl:with-param name="currentPage" select="$currentPage"/>
  </xsl:call-template>
</xsl:if>
</xsl:template>

<xsl:template name="Paging">
<xsl:param name="pCurrentPageNumber" select="pageNumber"/>
<xsl:param name="pRecordsPerPage" select="displayCount"/>
<xsl:param name="pPecordCount" select="total_results/@count"/>

<xsl:if test="$pPecordCount > $pRecordsPerPage">

 
  <xsl:if test="$pCurrentPageNumber > 1">
   <li>
    <xsl:variable name="PrePageNumber" select="number($pCurrentPageNumber)-2"/>
    <a>
     <xsl:attribute name="href">
      <xsl:value-of select="concat('?use_jump=',$pCurrentPageNumber,'&jump_first_car_F=', 1+$PrePageNumber*$pRecordsPerPage ,'&current_page_this_search_F=', $PrePageNumber+1 )"/>
     </xsl:attribute>
     Previous <xsl:value-of select="$pRecordsPerPage" />
    </a>
   </li>
  </xsl:if>

 
  <xsl:variable name="pageCount" select="ceiling($pPecordCount div $pRecordsPerPage)"/>
  <xsl:variable name="nrOfPagesToDisplay" select="10"/>
  <xsl:variable name="temp" select="$pCurrentPageNumber+$nrOfPagesToDisplay"/>
  <xsl:variable name="middel" select="ceiling($temp div 2)-1"/>
  <xsl:variable name="start" select="number($middel)-5"/>
  <xsl:choose>
   <xsl:when test="$pCurrentPageNumber > 5 and $start > 5">
    <xsl:call-template name="for.loop">
     <xsl:with-param name="i" select="number($start)-5"/>
     <xsl:with-param name="count" select="($pCurrentPageNumber+$nrOfPagesToDisplay)-1"/>
     <xsl:with-param name="currentPage" select="$pCurrentPageNumber"/>
    </xsl:call-template>
   </xsl:when>
   <xsl:when test="$start=0 or ($pageCount <= $nrOfPagesToDisplay)">
    <xsl:call-template name="for.loop">
     <xsl:with-param name="i" select="1"/>
     <xsl:with-param name="count" select="$nrOfPagesToDisplay"/>
     <xsl:with-param name="currentPage" select="$pCurrentPageNumber"/>
    </xsl:call-template>
   </xsl:when>
   <xsl:otherwise>
    <xsl:call-template name="for.loop">
     <xsl:with-param name="i" select="$start"/>
     <xsl:with-param name="count" select="($start+$nrOfPagesToDisplay)-1"/>
     <xsl:with-param name="currentPage" select="$pCurrentPageNumber"/>
    </xsl:call-template>
   </xsl:otherwise>
  </xsl:choose>
 

 
 
  <xsl:if test="$pageCount > $pCurrentPageNumber">
   <li>
    <a class="end">
     <xsl:attribute name="href">
      <xsl:value-of select="concat('?use_jump=',$pCurrentPageNumber,'&jump_first_car_F=', 1+($pCurrentPageNumber* $pRecordsPerPage) ,'&current_page_this_search_F=',$pCurrentPageNumber+1)"/>
     </xsl:attribute>
     Next <xsl:value-of select="$pRecordsPerPage" />
    </a>
   </li>
  </xsl:if>

</xsl:if>
</xsl:template>


* This source code was highlighted with Source Code Highlighter.


The template for.loop implement "for(int=0; i<> and the parametrs i is start index and the parametr count is length.

How can use it

In order to use the paging template you only have to call it with parametrs. The pCurrentPageNumber parametr is current page number or selected page number, the pRecordsPerPage parametr is the number of records per page,the pPecordCount parametr is record count.

For example:


<xsl:call-template name="Paging">

<xsl:with-param name="pCurrentPageNumber" select="pageNumber"/>
<xsl:with-param name="pRecordsPerPage" select="displayCount"/>
<xsl:with-param name="pPecordCount" select="total_results/@count"/>
</xsl:call-template>

No comments:

Post a Comment