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

XSLT:当Sum节点存在有效值时分组拼接Time节点内容

XSLT 1.0 实现节点分组拼接

需要在XSLT 1.0环境下处理输入XML的节点:将从含有效值的开始,到下一个含有效值的之前的所有

输入XML

<root>
    <row>
         <Time>Debit</Time>
         <Sum>(874,516.25)</Sum>
   </row>
    <row>
           <Time>TMU/2023/1059 A</Time> 
           <Sum></Sum> 
  </row>
   <row> 
          <Time>TMU/2023/1019 A</Time>
           <Sum></Sum>
    </row>
     <row>
       <Time>TMU/2023/1020 A</Time>
       <Sum></Sum>
     </row>
<row>
    <Time>Debit</Time>
  <Sum>(664,297.52)</Sum> 
 </row>
 <row>
        <Time>56011846 A</Time>
         <Sum></Sum>
         </row>
</root>

当前使用的XSLT代码(存在问题)

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- recursive named template -->
    <xsl:template name="hm">
        <xsl:param name="amount"/>
        <xsl:param name="pos"/>
        <xsl:for-each select="../row">
            <xsl:if test="$amount = Sum and $pos = position()"></xsl:if>
            <xsl:choose>
                <xsl:when test="string-length(Sum) &gt; 0">
                    <xsl:value-of select="Time"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="', '"/>
                    <xsl:value-of select="Time"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
    </xsl:template>
                        <Reference>
                            <xsl:call-template name="hm">
                                <xsl:with-param name="amount" select="Sum"/>
                                <xsl:with-param name="pos" select="position()"/>
                            </xsl:call-template>
                        </Reference>
                    </Payment>
                </xsl:if>
            </xsl:for-each>
        </Trailer>
    </xsl:template>
</xsl:stylesheet>

当前错误输出

<Trailer> 
         <Payment>  
          <Reference>Debit,TMU/2023/1059 A ,TMU/2023/1019 A ,TMU/2023/1020 A, Debit,56011846 A 
</Reference> 
          </Payment> 
          <Payment> 
           <Reference>Debit,TMU/2023/1059 A ,TMU/2023/1019 A ,TMU/2023/1020 A, Debit,56011846 A 
</Reference> 
           </Payment>
    </Trailer>

期望输出

<Trailer> 
    <Payment> 
     <Reference>Debit,TMU/2023/1059 A ,TMU/2023/1019 A ,TMU/2023/1020 A </Reference> 
    </Payment> 
    <Payment> 
     <Reference> Debit,56011846 A </Reference>
    </Payment>
    </Trailer>

修正后的XSLT代码

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 匹配根节点,输出Trailer容器 -->
    <xsl:template match="/root">
        <Trailer>
            <!-- 仅处理包含有效Sum的row节点(作为分组起始) -->
            <xsl:apply-templates select="row[string-length(Sum) > 0]"/>
        </Trailer>
    </xsl:template>

    <!-- 处理每个分组起始的row节点 -->
    <xsl:template match="row[string-length(Sum) > 0]">
        <Payment>
            <Reference>
                <!-- 输出当前row的Time -->
                <xsl:value-of select="Time"/>
                <!-- 递归拼接后续的空Sum row的Time,直到遇到下一个有效Sum row -->
                <xsl:call-template name="collect-following-times">
                    <xsl:with-param name="current-node" select="following-sibling::row[1]"/>
                </xsl:call-template>
            </Reference>
        </Payment>
    </xsl:template>

    <!-- 递归收集后续空Sum row的Time -->
    <xsl:template name="collect-following-times">
        <xsl:param name="current-node"/>
        <!-- 判断当前节点存在且Sum为空 -->
        <xsl:if test="$current-node and string-length($current-node/Sum) = 0">
            <xsl:value-of select="concat(', ', $current-node/Time)"/>
            <!-- 递归处理下一个兄弟节点 -->
            <xsl:call-template name="collect-following-times">
                <xsl:with-param name="current-node" select="$current-node/following-sibling::row[1]"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <!-- 忽略其他非目标节点 -->
    <xsl:template match="text()"/>
</xsl:stylesheet>

代码说明

  1. 分组逻辑:以含有效Sum的row为分组起点,仅对这些节点应用模板,确保每个分组对应一个Payment节点。
  2. 递归收集:通过collect-following-times模板递归遍历当前起始节点的后续兄弟节点,仅拼接Sum为空的row的Time内容,直到遇到下一个含有效Sum的row或节点结束。
  3. 输出控制:直接从起始节点的Time开始,后续每个符合条件的Time前添加, 分隔符,避免多余分隔符。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 18:44:54