基于旧版XSLT实现XML人员节点分页(每页3条)的技术求助
适配旧版XSLT 1.0的人员信息分页解决方案
需求说明
需要将给定的XML人员信息实现分页显示,每页最多展示3个<prsn>节点,同时显示每个节点的姓名、年龄、地址、城市等属性。现有方案在旧版XSLT 1.0处理器中无法正常工作,需提供兼容方案直至切换到Saxon处理器。
原始XML数据
<persns> <prsn> <fname>Smith</fname> <lname>Milton</lname> <age>44</age> <addrss>5th summer st, mntb</addrss> <city>Portland</city> </prsn> <prsn> <fname>Ken</fname> <lname>Jackson</lname> <age>37</age> <addrss>19th Penfield ave, brtcl</addrss> <city>Kelowna</city> </prsn> <prsn> <fname>Susan</fname> <lname>Arkland</lname> <age>48</age> <addrss>34th Mansfield st, sgtp</addrss> <city>Raleigh</city> </prsn> <prsn> <fname>George</fname> <lname>Bond</lname> <age>35</age> <addrss>5th drive, mntb</addrss> <city>Albany</city> </prsn> <prsn> <fname>Ron</fname> <lname>Davis</lname> <age>37</age> <addrss>12th Greenfield ave, brtcl</addrss> <city>Pheonix</city> </prsn> <prsn> <fname>Marie-Ann</fname> <lname>Spencer</lname> <age>48</age> <addrss>273 Simpson square</addrss> <city>Oklahoma</city> </prsn> <prsn> <fname>David</fname> <lname>Rhonson</lname> <age>45</age> <addrss>255 Lakeland Terrace, mi</addrss> <city>Livonia</city> </prsn> </persns>
用户尝试的XSLT模板
第一个模板(仅触发此模板)
<xsl:variable name="frme" select="3" /> <xsl:template match ="persns"> <xsl:apply-templates select="prsn[position()mod$frme=1]"/> </xsl:template>
第二个模板(未生效)
<xsl:template match="/prsn"> <!-- do some html table formatting and display those particular prsn's name, age etc --> </xsl:template>
兼容XSLT 1.0的解决方案
以下是完全适配XSLT 1.0处理器的分页实现,通过递归处理每页起始节点、使用XSLT 1.0原生语法完成分页逻辑:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 定义每页展示的人员数量 --> <xsl:variable name="page-size" select="3" /> <!-- 匹配根节点,初始化分页流程 --> <xsl:template match="/persns"> <html> <body> <!-- 启动第一页的处理,从第一个prsn节点开始 --> <xsl:apply-templates select="prsn[position() = 1]" mode="page" /> </body> </html> </xsl:template> <!-- 分页处理模板:负责生成单页的HTML结构 --> <xsl:template match="prsn" mode="page"> <!-- 计算当前页码 --> <h2>第<xsl:value-of select="floor((position() - 1) div $page-size) + 1" />页</h2> <!-- 生成人员信息表格 --> <table border="1"> <tr> <th>姓名</th> <th>年龄</th> <th>地址</th> <th>城市</th> </tr> <!-- 选取当前页的所有人员:当前节点 + 后续最多2个兄弟节点 --> <xsl:apply-templates select=". | following-sibling::prsn[position() < $page-size]" /> </table> <hr /> <!-- 递归处理下一页:找到当前页最后一个节点的下一个兄弟节点作为新页起始 --> <xsl:apply-templates select="following-sibling::prsn[$page-size]" mode="page" /> </xsl:template> <!-- 单个人员信息模板:负责渲染一行人员数据 --> <xsl:template match="prsn"> <tr> <td><xsl:value-of select="concat(fname, ' ', lname)" /></td> <td><xsl:value-of select="age" /></td> <td><xsl:value-of select="addrss" /></td> <td><xsl:value-of select="city" /></td> </tr> </xsl:template> </xsl:stylesheet>
方案要点说明
- 修正模板匹配问题:原第二个模板使用
/prsn匹配路径错误,<prsn>是<persns>的子节点,直接匹配prsn即可正确触发模板。 - XSLT 1.0兼容语法:避免使用XSLT 2+特性,用
floor((position()-1) div $page-size)+1计算页码,通过following-sibling选取同页的其他节点。 - 递归分页逻辑:通过带
mode="page"的模板递归处理每一页的起始节点,直到没有剩余人员节点为止,自动生成所有分页内容。
内容的提问来源于stack exchange,提问作者mirexS
相关产品推荐
相关产品推荐

