在XSL循环中使用变量存储动态值并实现新记录时重置
解决XSL循环内跟踪/重置变量的问题
我帮你梳理下这个问题哈——首先得明确XSLT里变量的核心特性:变量是一次性赋值的,一旦定义就不能修改它的值,所以你原来想通过更新curr_temp_emp_no来跟踪上一条记录的思路,在XSLT里是行不通的。不过咱们可以通过节点上下文对比或者分组的方式,实现“每次处理新记录时对比上一条emp_no”的需求,下面分不同XSLT版本给你具体方案:
方案一:XSLT 1.0(兼容旧环境)
方式1:直接对比前一条节点
不需要提前定义全局变量,每次循环直接通过节点轴获取上一条同层级的记录,自动实现“每次处理新记录时重置对比基准”:
<xsl:for-each select="/data/test/loof/super_incompleted"> <!-- 获取前一条记录的emp_no,第一条记录时这个值为空 --> <xsl:variable name="prev_emp_no" select="preceding-sibling::super_incompleted[1]/emp_no"/> <xsl:choose> <!-- 第一条记录,或者当前emp_no和上一条不同时执行 --> <xsl:when test="emp_no != $prev_emp_no or not($prev_emp_no)"> <xsl:value-of select="emp_no"/> <fo:inline> - </fo:inline> <!-- 这里放你需要输出的其他内容 --> </xsl:when> <xsl:otherwise> <!-- 当emp_no和上一条相同时的处理逻辑(可选) --> </xsl:otherwise> </xsl:choose> </xsl:for-each>
方式2:Muenchian分组(适合按emp_no批量处理)
如果你的需求是把相同emp_no的记录归为一组处理,可以用XSLT 1.0经典的Muenchian分组法:
<!-- 先定义分组的键,按emp_no分组 --> <xsl:key name="emp-group" match="super_incompleted" use="emp_no"/> <!-- 遍历每个分组的第一条记录 --> <xsl:for-each select="/data/test/loof/super_incompleted[generate-id() = generate-id(key('emp-group', emp_no)[1])]"> <!-- 输出分组的emp_no --> <xsl:value-of select="emp_no"/> <fo:inline> - </fo:inline> <!-- 遍历当前分组下的所有记录 --> <xsl:for-each select="key('emp-group', emp_no)"> <!-- 处理分组内的每条具体记录 --> </xsl:for-each> </xsl:for-each>
方案二:XSLT 2.0及以上(语法更简洁)
如果你的环境支持XSLT 2.0+,可以用更强大的分组语法:
方式1:for-each-group分组
直接按emp_no分组,代码更直观:
<xsl:for-each-group select="/data/test/loof/super_incompleted" group-by="emp_no"> <!-- 获取当前分组的emp_no --> <xsl:value-of select="current-grouping-key()"/> <fo:inline> - </fo:inline> <!-- 遍历当前分组的所有记录 --> <xsl:for-each select="current-group()"> <!-- 处理每条记录 --> </xsl:for-each> </xsl:for-each-group>
方式2:通过位置跟踪前一条记录
如果只是需要逐行对比上一条的值,也可以通过节点位置来获取:
<xsl:variable name="all_records" select="/data/test/loof/super_incompleted"/> <xsl:for-each select="$all_records"> <xsl:variable name="current_pos" select="position()"/> <!-- 获取上一条记录的emp_no --> <xsl:variable name="prev_emp_no" select="$all_records[$current_pos - 1]/emp_no"/> <xsl:if test="emp_no != $prev_emp_no or $current_pos = 1"> <xsl:value-of select="emp_no"/> <fo:inline> - </fo:inline> </xsl:if> </xsl:for-each>
总的来说,核心就是避开“修改变量”的思路,利用XSLT的节点上下文或分组特性来实现你要的逻辑~
内容的提问来源于stack exchange,提问作者aim_thebest
相关产品推荐
相关产品推荐

