You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XSLT实现编辑元素按每n个分组拆分并生成带分页的page结构

解决方案

你的需求不需要用到Muenchian分组,固定大小的分页用按位置截断的递归模板就能实现,核心修改逻辑如下:

  1. 保留原有subfilter的合法性校验逻辑,先筛选出符合要求的article节点
  2. 对每个合法article的edit节点先按version排序,存储为临时节点集
  3. 用递归模板按每页最多2个edit的规则拆分生成page节点
  4. 先把所有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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 00:27:00