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

XSLT 1.0需求:重复BATCH元素属性加后缀及校验文本

XSLT 1.0 重复BATCH元素处理修正方案

我需要在XSLT 1.0中实现以下逻辑:当<BATCH>元素文本重复时(首个出现的元素除外),给对应的<MOTOR>元素的No_ID属性添加_1、_2……后缀,同时添加“CHECK IT”文本。

现有的XSLT代码存在两个问题:

  • 给首个出现的重复元素也添加了后缀
  • 后缀用的是元素的全局位置序号,而非该BATCH值的重复次数序号

输入XML

<ROOT>
    <MOTORS>
        <ELEMENT>
            <NUMBER>
                <BATCH>ELEC_KN</BATCH>
            </NUMBER>
        </ELEMENT>
        
        <ELEMENT>
            <NUMBER>
                <BATCH>ELEC_LJ</BATCH>
            </NUMBER>
        </ELEMENT>
        
        <ELEMENT>
            <NUMBER>
                <BATCH>DIESEL_ZT</BATCH>
            </NUMBER>
        </ELEMENT>
        
        <ELEMENT>
            <NUMBER>
                <BATCH>ELEC_LJ</BATCH>
            </NUMBER>
        </ELEMENT>
        
        <ELEMENT>
            <NUMBER>
                <BATCH>DIESEL_ZT</BATCH>
            </NUMBER>
        </ELEMENT>
        
        <ELEMENT>
            <NUMBER>
                <BATCH>DIESEL_ZT</BATCH>
            </NUMBER>
        </ELEMENT>
        
    </MOTORS>   
</ROOT>

现有XSLT代码

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  
<xsl:template match="/">
  <Before_sale>
            <xsl:for-each select="//ROOT/MOTORS/ELEMENT">
                
                    
                    
                    <xsl:variable name="BATCH">
                      <xsl:value-of select="normalize-space(NUMBER/BATCH)"/>
                    </xsl:variable>
                    
                    <xsl:variable name="nameCount" select="count(//ELEMENT[NUMBER/BATCH/text() = current()/NUMBER/BATCH/text()])"/>

                    <xsl:variable name="REPEAT">
                        <xsl:choose>
                            <xsl:when test="$nameCount &gt; 1">
                                <xsl:value-of select="$BATCH"/>
                                <xsl:text>_</xsl:text>
                                <xsl:number count="//ELEMENT[NUMBER/BATCH/text() = current()/NUMBER/BATCH/text()]" level="any"/>
                                
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:value-of select="$BATCH"/>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:variable>
                    
                    <MOTOR No_ID="{$REPEAT}">
                      <xsl:if test="$REPEAT != $BATCH">
                        <xsl:text> CHECK IT  </xsl:text>
                      </xsl:if>
                    </MOTOR>
                
             
            </xsl:for-each>
        </Before_sale> 
        
</xsl:template>
  
</xsl:stylesheet>

期望输出XML

<Before_sale>
   <MOTOR No_ID="ELEC_KN"/>
   <MOTOR No_ID="ELEC_LJ"></MOTOR> <!-- 首次出现的元素,不加后缀和校验文本 -->
   <MOTOR No_ID="DIESEL_ZT"> CHECK IT  </MOTOR> <!-- 首次出现的元素,不加后缀和校验文本 -->
   <MOTOR No_ID="ELEC_LJ_1"> CHECK IT  </MOTOR> <!-- 首次重复,添加后缀_1及校验文本 -->
   <MOTOR No_ID="DIESEL_ZT_1"/> <!-- 首次重复,添加后缀_1 -->
   <MOTOR No_ID="DIESEL_ZT_2"> CHECK IT  </MOTOR> <!-- 第二次重复,添加后缀_2及校验文本 -->
</Before_sale>

修正后的XSLT代码

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  
  <xsl:template match="/">
    <Before_sale>
      <xsl:for-each select="ROOT/MOTORS/ELEMENT">
        <xsl:variable name="currentBatch" select="normalize-space(NUMBER/BATCH)"/>
        <!-- 计算当前元素是同BATCH值中的第几个实例(从1开始) -->
        <xsl:variable name="instanceIndex" select="count(preceding-sibling::ELEMENT[NUMBER/BATCH = $currentBatch]) + 1"/>
        
        <xsl:variable name="noIdValue">
          <xsl:choose>
            <!-- 仅当不是第一个实例时添加后缀 -->
            <xsl:when test="$instanceIndex > 1">
              <xsl:value-of select="concat($currentBatch, '_', $instanceIndex - 1)"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="$currentBatch"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:variable>
        
        <MOTOR No_ID="{$noIdValue}">
          <!-- 非首个实例时添加CHECK IT文本 -->
          <xsl:if test="$instanceIndex > 1">
            <xsl:text> CHECK IT  </xsl:text>
          </xsl:if>
        </MOTOR>
      </xsl:for-each>
    </Before_sale>
  </xsl:template>
  
</xsl:stylesheet>

关键修改说明

  1. 计算实例序号:使用count(preceding-sibling::ELEMENT[NUMBER/BATCH = $currentBatch]) + 1获取当前元素在同BATCH值中的位置序号,从1开始计数
  2. 后缀逻辑调整:仅当instanceIndex > 1时,用$instanceIndex - 1作为后缀数字,确保首次重复显示_1,第二次重复显示_2
  3. 条件判断优化:直接通过实例序号判断是否需要添加后缀和文本,避免原代码中对全局计数的错误依赖

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:57:04