使用XSLT进行分页显示数据

在处理大量数据时,将数据分页显示是一种常见的需求。本文将展示如何使用XSL Transformation样式表创建基于数字的分页。以XML格式的Northwind数据库数据为例,以下是数据文件的一部分:

<Northwind> <Products> <ProductName>Chai</ProductName> <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>

根元素是<Northwind>,详细信息存储在<Products>中。

创建基于数字的分页

分页按钮作为带有参数的链接创建,其中页码作为URL的一部分传递,例如:default.aspx?page=5。在代码中创建此类链接的一种方法在这里描述。但本文的目标是使用纯XSL转换来创建这些链接。转换应用于System.Web.UI.WebControls.Xml控件中,该控件在default.aspx中创建为:

<asp:Xml id="Xml1" runat="server" DocumentSource="northwind_products.xml" TransformSource="default.xslt"> </asp:Xml>

XML源从northwind_products.xml加载,XSL转换样式表从default.xslt加载。在继续转换样式表之前,需要指出Page_Load处理程序中的以下代码。这段代码获取?page=参数,创建XsltArgumentList并将CurrentPage参数传递给转换。

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;

CurrentPage参数用于显示正确的数据页面,并创建到其他页面的适当链接。转换样式表的其他可选参数是PageSizeMaxPagesPageSize是每页显示的项目数。MaxPages定义了页面链接的最大数量。当前页面的按钮不显示为链接。例如,如果CurrentPage=50MaxPages=5,则将得到以下结果:"First ... [48] [49] [50] [51] [52] ... Last",其中[50]是一个没有链接的按钮。下面提供了渲染按钮的XSL模板:

<!-- 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> <xsl:when test="(position() > ($CurrentPage - ceiling($MaxPages div 2)) or position() > (last() - $MaxPages)) and ((position() < $CurrentPage + $MaxPages div 2) or (position() < 1 + $MaxPages))"> <xsl:if test="position()=$CurrentPage"> [<xsl:value-of select="position()"/>] </xsl:if> <!-- skipped code which creates links --> </xsl:when> </xsl:choose> </xsl:for-each> </xsl:template>

这段代码的有趣部分在于选择适当的节点。第一步是选择每页的一个节点 - 相关的XPath表达式是Products[((position()-1) mod $PageSize = 0)]。结果集将包含与页面数量相同的元素。第二步是只选择$MaxPages中的它们,这些围绕$CurrentPage。最后,使用position()语句渲染结果。为了减少这个示例的大小,省略了创建链接的部分代码,但可以从<xsl:value-of select="position()"/>语句中了解它是如何完成的。

根据页码过滤数据

显示表格的模板相当简单:

<xsl:template match="Products"> <xsl:choose> <xsl:when test="(position() >= 1 + ($CurrentPage - 1) * $PageSize) and (position() < (1 + $CurrentPage * $PageSize))"> <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>

突出显示的XPath表达式用于选择适当页面的数据。请注意,产品名称存储为属性,这意味着将使用@ProductName语句来选择它。

要点

毫无疑问,创建分页按钮有更简单的方法,例如考虑DataGrid。但是考虑可移植性。在本文中,只使用C#将参数传递给XSLT解析器,但XSLT解析器存在于各种编程语言和平台上。希望代码对那些关心兼容性和可移植性的人有用。此外,还可以使用XSLT创建基于字母的分页。如果有人有实际需要,请给留言。感谢兴趣,记住意见非常宝贵。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485