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

如何在XQuery中对同一节点内空格/减号分隔的数字求和?

解决方案:XML 标签内数字计算转换

针对你需要将标签内的数字(空格分隔求和、连字符分隔求差)替换为计算结果的需求,下面提供两种XSLT实现方案,适配不同版本的XSLT处理器:


XSLT 2.0 简洁实现

XSLT 2.0自带tokenize函数,处理字符串拆分非常方便:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 复制原XML的所有节点和属性,保留结构 -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- 专门处理<num>标签 -->
    <xsl:template match="num">
        <xsl:copy>
            <xsl:choose>
                <!-- 处理连字符减法,比如"4-2" -->
                <xsl:when test="contains(., '-')">
                    <xsl:variable name="nums" select="tokenize(., '-')" />
                    <xsl:value-of select="number($nums[1]) - number($nums[2])" />
                </xsl:when>
                <!-- 处理空格分隔的数字求和,比如"1 5 7" -->
                <xsl:otherwise>
                    <xsl:variable name="nums" select="tokenize(., '\s+')" />
                    <xsl:value-of select="sum($nums)" />
                </xsl:otherwise>
            </xsl:choose>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

逻辑说明

  • 第一个模板是身份模板,负责原样复制XML中除外的所有内容,保证原有结构不变。
  • 第二个模板匹配标签:
    • 用contains(., '-')判断是否为减法表达式,拆分后计算差值。
    • 其他情况默认是空格分隔的数字,用tokenize(., '\s+')拆分(支持多个连续空格),直接调用sum()求和。

XSLT 1.0 兼容方案

如果只能使用XSLT 1.0(无tokenize函数),可以用递归模板实现字符串拆分:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 身份模板:复制原结构 -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- 处理<num>标签 -->
    <xsl:template match="num">
        <xsl:copy>
            <xsl:choose>
                <!-- 处理减法:拆分连字符两侧的数字 -->
                <xsl:when test="contains(., '-')">
                    <xsl:variable name="left" select="substring-before(., '-')" />
                    <xsl:variable name="right" select="substring-after(., '-')" />
                    <xsl:value-of select="number($left) - number($right)" />
                </xsl:when>
                <!-- 调用递归求和模板处理空格分隔的数字 -->
                <xsl:otherwise>
                    <xsl:call-template name="sum-space-separated">
                        <xsl:with-param name="str" select="." />
                    </xsl:call-template>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:copy>
    </xsl:template>

    <!-- 递归模板:累加空格分隔的数字 -->
    <xsl:template name="sum-space-separated">
        <xsl:param name="str" />
        <xsl:param name="total" select="0" />
        
        <xsl:choose>
            <!-- 还有空格,继续拆分累加 -->
            <xsl:when test="contains($str, ' ')">
                <xsl:variable name="num" select="substring-before($str, ' ')" />
                <xsl:call-template name="sum-space-separated">
                    <xsl:with-param name="str" select="normalize-space(substring-after($str, ' '))" />
                    <xsl:with-param name="total" select="$total + number($num)" />
                </xsl:call-template>
            </xsl:when>
            <!-- 处理最后一个数字,返回总和 -->
            <xsl:otherwise>
                <xsl:value-of select="$total + number($str)" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

逻辑说明

  • 减法部分用substring-before和substring-after直接拆分数字。
  • 求和部分通过递归模板逐次拆分第一个空格前的数字,累加到总和,normalize-space用来处理连续空格的情况。

测试效果

输入XML:

<test> 
    <num>1 5 7</num> 
    <num>4-2</num> 
</test>

转换后输出:

<test> 
    <num>13</num> 
    <num>2</num> 
</test>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:55:31