|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionWhen displaying large sets of data, it is sometimes necessary to split data into pages. In this article, I will show how to create a number-based paging by using the XSL Transformation style sheet. For this example, I will take data from the Northwind database in XML format. Below is an excerpt from the data file. <Northwind>
<Products ProductName="Chai">
<ProductID>1</ProductID>
<SupplierID>1</SupplierID>
<CategoryID>1</CategoryID>
<QuantityPerUnit>10 boxes x 20 bags</QuantityPerUnit>
<UnitPrice>18.0000</UnitPrice>
<UnitsInStock>39</UnitsInStock>
<UnitsOnOrder>0</UnitsOnOrder>
<ReorderLevel>10</ReorderLevel>
<Discontinued>false</Discontinued>
</Products>
</Northwind>
The root element is Creating number-based pagingThe page buttons are created as links with parameters where page numbers are passed as a part of the URL, i.e. default.aspx?page=5. One way to create such links in code is described here. But the goal of the current article is to create those links using pure XSL transformation. The transformation is applied within the <asp:Xml id="Xml1" runat="server"
DocumentSource="northwind_products.xml"
TransformSource="default.xslt"></asp:Xml>
The XML source is loaded from the northwind_products.xml, and the XSL Transformation style sheet is loaded from the default.xslt. Before we proceed to the transformation style sheet, I need to point out the following code in the double CurrentPage = 1D;
if(Request.Params["page"] != null)
CurrentPage = Double.Parse(Request.Params["page"]);
XsltArgumentList xal = new XsltArgumentList();
xal.AddParam("CurrentPage", String.Empty, CurrentPage);
Xml1.TransformArgumentList = xal;
The The button for a current page is not displayed as a link. For example, if the <!-- displays page buttons -->
<xsl:template name="Pages">
<xsl:variable name="TotalItems" select="count(Products)" />
<xsl:variable name="Pages" select="ceiling($TotalItems div $PageSize)" />
<!-- select first element of each page -->
<xsl:for-each select="Products[((position()-1) mod $PageSize = 0)]">
<!-- display the appropriate portion of page links -->
<xsl:choose>
<!-- the expression below selects only MaxPages number of pages -->
<xsl:when test="(position() > ($CurrentPage - ceiling($MaxPages div 2)) or
position() > (last() - $MaxPages)) and
((position() < $CurrentPage + $MaxPages div 2) or
(position() < 1 + $MaxPages))">
<!-- render non-link page button for CurrentPage -->
<xsl:if test="position()=$CurrentPage">
[ <xsl:value-of select="position()"/> ]
</xsl:if>
<!-- skipped code which creates links -->
</xsl:choose>
</xsl:for-each>
</xsl:template>
The interesting part of this code is where the appropriate nodes are selected. The first step is to select one node of each page - the related XPath expression is Filtering the data according to page numberTemplate, which displays the table is rather simple: <xsl:template match="Products">
<xsl:choose>
<xsl:when test="(position() >= 1 + ($CurrentPage - 1) * $PageSize) and
(position() < (1 + $CurrentPage * $PageSize))">
<!-- display table rows here -->
<tr>
<td><xsl:value-of select="position()"/></td>
<td><xsl:value-of select="@ProductName"/></td>
<td><xsl:value-of select="format-number(UnitPrice,'$#.00')"/></td>
<td align="center"><xsl:value-of select="UnitsInStock"/></td>
</tr>
</xsl:when>
</xsl:choose>
</xsl:template>
The XPath expression which selects data of the appropriate page is highlighted in bold. Note that product name is stored as an attribute, which means that we will use Points of InterestNo doubt that there exists a simpler way of creating page buttons, consider
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||