XSLT实现编辑元素按每n个分组拆分并生成带分页的page结构
解决方案
你的需求不需要用到Muenchian分组,固定大小的分页用按位置截断的递归模板就能实现,核心修改逻辑如下:
- 保留原有subfilter的合法性校验逻辑,先筛选出符合要求的article节点
- 对每个合法article的edit节点先按version排序,存储为临时节点集
- 用递归模板按每页最多2个edit的规则拆分生成page节点
- 先把所有page节点统一存入临时节点集后再遍历输出,确保page-break的位置准确(仅最后一个page后不加分页符)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" xmlns:msxsl="urn:schemas-microsoft-com:xslt"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <!-- 定义每页最多容纳的edit数量,修改该值即可调整分页大小 --> <xsl:variable name="page-size" select="2" /> <xsl:template match="/"> <pages> <!-- 第一步:筛选符合发布要求的article --> <xsl:variable name="valid-articles"> <xsl:apply-templates select="/articles/article[@publishable='true']" mode="subfilter"/> </xsl:variable> <!-- 第二步:生成所有page节点到临时集合 --> <xsl:variable name="all-pages"> <xsl:apply-templates select="msxsl:node-set($valid-articles)/article" mode="gen-pages"/> </xsl:variable> <!-- 第三步:输出page和对应的分页符 --> <xsl:variable name="page-nodes" select="msxsl:node-set($all-pages)/page" /> <xsl:for-each select="$page-nodes"> <xsl:copy-of select="." /> <xsl:if test="position() != last()"> <page-break/> </xsl:if> </xsl:for-each> </pages> </xsl:template> <!-- 原有合法性校验逻辑保留 --> <xsl:template match="article" mode="subfilter"> <xsl:variable name="id_of_latest_edit"> <xsl:for-each select="edits/article"> <xsl:sort data-type="number" select="@version"/> <xsl:if test="position()=last()"> <xsl:value-of select="@id"/> </xsl:if> </xsl:for-each> </xsl:variable> <xsl:if test="@id = $id_of_latest_edit or not(edits/article)"> <xsl:copy-of select="."/> </xsl:if> </xsl:template> <!-- 为单个合法article生成所有对应的page节点 --> <xsl:template match="article" mode="gen-pages"> <xsl:variable name="title" select="@title" /> <!-- 先把edit按version升序排序后存为临时节点集 --> <xsl:variable name="sorted-edits"> <xsl:for-each select="edits/article"> <xsl:sort select="@version" data-type="number" order="ascending"/> <xsl:copy-of select="." /> </xsl:for-each> </xsl:variable> <xsl:variable name="edits" select="msxsl:node-set($sorted-edits)/article" /> <!-- 调用递归模板生成分页 --> <xsl:call-template name="build-pages"> <xsl:with-param name="edits" select="$edits" /> <xsl:with-param name="title" select="$title" /> <xsl:with-param name="start-pos" select="1" /> </xsl:call-template> </xsl:template> <!-- 递归分页模板 --> <xsl:template name="build-pages"> <xsl:param name="edits" /> <xsl:param name="title" /> <xsl:param name="start-pos" /> <page title="{$title}"> <xsl:apply-templates select="$edits[position() >= $start-pos and position() < $start-pos + $page-size]" mode="editdetails" /> </page> <!-- 还有剩余edit则继续生成下一页 --> <xsl:if test="$start-pos + $page-size <= count($edits) + 1"> <xsl:call-template name="build-pages"> <xsl:with-param name="edits" select="$edits" /> <xsl:with-param name="title" select="$title" /> <xsl:with-param name="start-pos" select="$start-pos + $page-size" /> </xsl:call-template> </xsl:if> </xsl:template> <xsl:template match="article" mode="editdetails"> <edit version="{@version}"/> </xsl:template> </xsl:stylesheet>
内容的提问来源于stack exchange,提问作者woodduck
相关产品推荐
相关产品推荐

