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

如何在XSLT 1.0中按节点值总和生成连续数字并分页?

问题描述

给定如下XML:第一个line节点(ref=1)下所有name元素值总和为5(2+3),第二个line节点(ref=2)总和为3。要求为每个line生成从1到对应总和的连续数字,同时按每个name的值生成单独页面,总计8页。现有XSLT 1.0代码无法实现预期效果,需修正。

预期输出

line 1
number 1
number 2
number 3
number 4
number 5

line 2
number 1
number 2
number 3

XML输入

<?xml version="1.0" encoding="UTF-8"?>
<root parent="a">
   <line ref="1">
    <child line="1">
        
        <name id="school">2</name>
       
    </child>
    <child line="2">
        <name id="school">3</name>
    </child>
  </line>
    
    <line ref="2">
        <child line="1">
            <name id="school">1</name>
        </child>
        <child line="2">
            <name id="school">2</name>
        </child>
    </line>
 </root>

现有XSLT的核心问题

  1. 数字生成逻辑错误:使用(//node())[position() <= $pack]遍历XML节点而非生成指定数量的连续数字,完全偏离需求。
  2. 未按line分组计算总和:仅按单个child的name值重复输出,未计算每个line的总和并生成连续序列。
  3. 分页控制混乱:分页标记未与name的数量正确绑定,无法实现每个name对应单独页面的要求。

修正后的XSLT 1.0代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    xmlns:fo="http://www.w3.org/1999/XSL/Format">
    
    <xsl:decimal-format name="generalFormat" grouping-separator="," decimal-separator="." />
    
    <!-- 主模板:生成FO根结构并遍历所有line节点 -->
    <xsl:template match="/">
        <fo:root>
            <fo:layout-master-set>
                <fo:simple-page-master master-name="ManufacturLabelSize" page-height="100mm" page-width="100mm">
                    <fo:region-body margin-top="15mm" />
                </fo:simple-page-master>
                <fo:page-sequence-master master-name="ManufacturLabelSize-portrait">
                    <fo:repeatable-page-master-alternatives>
                        <fo:conditional-page-master-reference master-reference="ManufacturLabelSize" />
                    </fo:repeatable-page-master-alternatives>
                </fo:page-sequence-master>
            </fo:layout-master-set>
            
            <xsl:apply-templates select="root/line" />
        </fo:root>
    </xsl:template>
    
    <!-- 处理单个line节点:生成line总和序列 + 每个child的单独页面 -->
    <xsl:template match="line">
        <!-- 生成当前line的总和数字序列 -->
        <fo:page-sequence master-reference="ManufacturLabelSize-portrait">
            <fo:flow flow-name="xsl-region-body">
                <fo:block>line <xsl:value-of select="@ref" /></fo:block>
                <xsl:variable name="total" select="sum(child/name[@id='school'])" />
                <xsl:call-template name="generate-numbers">
                    <xsl:with-param name="current" select="1" />
                    <xsl:with-param name="max" select="$total" />
                </xsl:call-template>
            </fo:flow>
        </fo:page-sequence>
        
        <!-- 为每个child生成单独页面 -->
        <xsl:for-each select="child">
            <xsl:variable name="pack" select="name[@id='school']" />
            <fo:page-sequence master-reference="ManufacturLabelSize-portrait">
                <fo:flow flow-name="xsl-region-body">
                    <fo:block>child line <xsl:value-of select="@line" /></fo:block>
                    <xsl:call-template name="generate-numbers">
                        <xsl:with-param name="current" select="1" />
                        <xsl:with-param name="max" select="$pack" />
                    </xsl:call-template>
                </fo:flow>
            </fo:page-sequence>
        </xsl:for-each>
    </xsl:template>
    
    <!-- 递归模板:生成从current到max的连续数字 -->
    <xsl:template name="generate-numbers">
        <xsl:param name="current" />
        <xsl:param name="max" />
        
        <xsl:if test="$current <= $max">
            <fo:block>number <xsl:value-of select="$current" /></fo:block>
            <xsl:call-template name="generate-numbers">
                <xsl:with-param name="current" select="$current + 1" />
                <xsl:with-param name="max" select="$max" />
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
    
</xsl:stylesheet>

代码说明

  1. 主模板:初始化FO布局结构,遍历所有line节点进行处理。
  2. line处理逻辑:
    • 计算当前line下name值的总和,调用递归模板生成1到总和的连续数字。
    • 遍历每个child,根据其name的值生成单独页面,同样通过递归模板生成对应数量的数字。
  3. 递归数字生成:利用XSLT 1.0的递归特性实现连续数字序列生成,这是该版本下生成序列的标准方案。
  4. 页面布局简化:统一页面模板,无需区分首页和后续页面,减少冗余配置。

内容的提问来源于stack exchange,提问作者Akash

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 15:55:06