基于XSLT 2的XML移动端分页转换:每页3条记录(终篇)
维护费用XML转置分页的XSLT 2实现
需求说明
- 行列转置:首列为固定表头,其余列每页展示3条记录,适配移动端
- 计算字段规则:
- OB(期初余额):第一条记录取原XML的
OpngBlnce值,后续记录取上一条的**CB(期末余额)**值 - MUPA(月度维护费用):直接读取原XML的
mnthCrrntAmnt节点值 - TAP(应缴总额):计算公式为
OB + MUPA - TAPD(实缴总额):统计对应
upkShare下所有Rcpt/amnt节点的总和 - CB(期末余额):计算公式为
TAP - TAPD
- OB(期初余额):第一条记录取原XML的
- 表头规则:
- 首行第一列为固定文本
CrntNmbr - 首行后续列通过
xsl:for-each循环输出序号1、2、3 - 首列的表头内容通过变量定义
- 首行第一列为固定文本
原XML输入
<upkeepList> <upkShare month_year="03-17" post_dte="04-16-17" due="05-02-17"> <OpngBlnce>29</OpngBlnce> <mnthCrrntAmnt>45</mnthCrrntAmnt> <Rcpt dte="05-10-17" No="5815"> <amnt>50</amnt> <descrpt>"03/17-04/17" upkeep</descrpt> </Rcpt> </upkShare> <upkShare month_year="04_17-05_17" post_dte="06-05-17" due="06-30-17"> <OpngBlnce/> <mnthCrrntAmnt>64</mnthCrrntAmnt> <Rcpt dte="06-14-17" No="5858"> <amnt>57</amnt> <descrpt>"05/17" upkeep</descrpt> </Rcpt> </upkShare> <upkShare month_year="06_17" post_dte="07-16-17" due="07-30-17"> <OpngBlnce/> <mnthCrrntAmnt>41</mnthCrrntAmnt> <Rcpt dte="07-28-17" No="5948"> <amnt>50</amnt> <descrpt>"06/17" upkeep</descrpt> </Rcpt> </upkShare> <upkShare month_year="07_17" post_dte="08-16-17" due="08-31-17"> <OpngBlnce/> <mnthCrrntAmnt>31</mnthCrrntAmnt> <Rcpt dte="08-31-17" No="6002"> <amnt>53</amnt> <descrpt>"07/17" upkeep 1</descrpt> </Rcpt> </upkShare> <upkShare month_year="08_17" post_dte="09-19-17" due="09-31-17"> <OpngBlnce/> <mnthCrrntAmnt>41</mnthCrrntAmnt> <Rcpt dte="09-29-17" No="6026"> <amnt>41</amnt> <descrpt>"07/17" upkeep 1</descrpt> </Rcpt> </upkShare> <upkShare month_year="09_17" post_dte="10-16-17" due="10-31-17"> <OpngBlnce/> <mnthCrrntAmnt>34</mnthCrrntAmnt> <Rcpt dte="10-26-17" No="6050"> <amnt>34</amnt> <descrpt>"07/17" upkeep 1</descrpt> </Rcpt> </upkShare> </upkeepList>
XSLT 2转换代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" indent="yes" encoding="UTF-8"/> <!-- 定义首列表头内容变量 --> <xsl:variable name="columnHeaders"> <header>OB(期初余额)</header> <header>MUPA(月度维护费用)</header> <header>TAP(应缴总额)</header> <header>TAPD(实缴总额)</header> <header>CB(期末余额)</header> </xsl:variable> <!-- 分组:每页3条upkShare记录 --> <xsl:for-each-group select="/upkeepList/upkShare" group-by="(position() - 1) idiv 3"> <html> <head> <style> /* 移动端适配样式 */ table { width: 100%; border-collapse: collapse; margin-bottom: 20px; } th, td { border: 1px solid #ddd; padding: 8px; text-align: center; } th { background-color: #f2f2f2; } .pagination { text-align: center; margin-top: 10px; } .pagination a { margin: 0 5px; padding: 4px 8px; border: 1px solid #ddd; text-decoration: none; color: #333; } .pagination a.active { background-color: #4CAF50; color: white; border-color: #4CAF50; } </style> </head> <body> <table> <!-- 首行表头 --> <tr> <th>CrntNmbr</th> <xsl:for-each select="current-group()"> <th><xsl:value-of select="position()"/></th> </xsl:for-each> </tr> <!-- 循环输出首列的各个字段行 --> <xsl:for-each select="$columnHeaders/header"> <xsl:variable name="headerIndex" select="position()"/> <tr> <td><xsl:value-of select="."/></td> <!-- 处理当前分组内的每条记录 --> <xsl:for-each select="current-group()"> <xsl:variable name="currentPos" select="position()"/> <!-- 计算当前记录的OB值 --> <xsl:variable name="ob"> <xsl:choose> <xsl:when test="$currentPos = 1 and $headerIndex = 1"> <xsl:value-of select="number(OpngBlnce)"/> </xsl:when> <xsl:when test="$currentPos > 1 and $headerIndex = 1"> <!-- 取上一条记录的CB值 --> <xsl:variable name="prevItem" select="preceding-sibling::upkShare[1]"/> <xsl:value-of select="number($prevItem/OpngBlnce) + number($prevItem/mnthCrrntAmnt) - sum($prevItem/Rcpt/amnt)"/> </xsl:when> </xsl:choose> </xsl:variable> <!-- 计算MUPA --> <xsl:variable name="mupa" select="number(mnthCrrntAmnt)"/> <!-- 计算TAP --> <xsl:variable name="tap" select="$ob + $mupa"/> <!-- 计算TAPD --> <xsl:variable name="tapd" select="sum(Rcpt/amnt)"/> <!-- 计算CB --> <xsl:variable name="cb" select="$tap - $tapd"/> <!-- 根据当前表头索引输出对应值 --> <xsl:choose> <xsl:when test="$headerIndex = 1"> <td><xsl:value-of select="$ob"/></td> </xsl:when> <xsl:when test="$headerIndex = 2"> <td><xsl:value-of select="$mupa"/></td> </xsl:when> <xsl:when test="$headerIndex = 3"> <td><xsl:value-of select="$tap"/></td> </xsl:when> <xsl:when test="$headerIndex = 4"> <td><xsl:value-of select="$tapd"/></td> </xsl:when> <xsl:when test="$headerIndex = 5"> <td><xsl:value-of select="$cb"/></td> </xsl:when> </xsl:choose> </xsl:for-each> </tr> </xsl:for-each> </table> <!-- 分页区域 --> <div class="pagination"> <xsl:variable name="currentPage" select="position()"/> <xsl:variable name="totalPages" select="ceiling(count(/upkeepList/upkShare) div 3)"/> <xsl:if test="$currentPage > 1"> <a href="#page{currentPage - 1}">上一页</a> </xsl:if> <xsl:for-each select="1 to $totalPages"> <a href="#page{.}" class="{if . = $currentPage then 'active' else ''}"> <xsl:value-of select="."/> </a> </xsl:for-each> <xsl:if test="$currentPage < $totalPages"> <a href="#page{currentPage + 1}">下一页</a> </xsl:if> </div> </body> </html> </xsl:for-each-group> </xsl:stylesheet>
代码说明
- 使用
xsl:for-each-group按每3条记录分组,实现分页逻辑 - 通过变量
columnHeaders统一管理首列表头内容,便于后续修改维护 - 字段计算严格遵循需求:首条OB取原节点值,后续OB继承上一条的CB;其余字段通过对应公式计算
- 内置移动端适配CSS样式,确保表格在移动设备上自适应显示
- 分页区域实现了上一页、页码切换、下一页的基础导航功能
内容的提问来源于stack exchange,提问作者mirexS
相关产品推荐
相关产品推荐

