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

使用Saxon的XSLT 3.0流处理报错:存在多个消耗操作数

Saxon 11.2 XSLT 3.0流处理报错解决

问题说明

使用Saxon 11.2版本进行XSLT 3.0流处理时,同一模板中同时调用replace和contains字符串函数会触发报错:

Template rule is not streamable * There is more than one consuming operand

单独使用其中任意一个函数时,XSLT可正常运行。

示例输入XML

<?xml version="1.0" encoding="UTF-8"?>
<Update xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Request>
<List>
<RequestP><ManNumber>3B4</ManNumber></RequestP>
<RequestP><ManNumber>8T7_BE</ManNumber></RequestP>
<RequestP><ManNumber>3B5</ManNumber></RequestP>
<RequestP><ManNumber>5E9_BE</ManNumber></RequestP>
<RequestP><ManNumber>9X6</ManNumber></RequestP>
</List>
</Request>
</Update>

原报错XSLT代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="3.0" exclude-result-prefixes="#all">
   <xsl:output method="xml" omit-xml-declaration="no" indent="yes" />
   <xsl:mode streamable="yes" />
    <xsl:template match="List/RequestP/ManNumber">
            <ManNumber>
               <xsl:value-of select="replace(.,'_BE','')" />
            </ManNumber>  
        <xsl:if test="contains(.,'_BE')">
         <ManDescrip>BE</ManDescrip>
        </xsl:if>
   </xsl:template>
</xsl:stylesheet>

报错信息(中文翻译)

模板规则不支持流处理
  * 存在多个消费操作数:第6行的{<ManNumber {xsl:value-of}/>},以及第9行的{if(fn:contains(...)) then ... else ...}

解决方案

流处理模式下,源节点只能被一次性消费(即读取其内容一次),replace和contains都会读取节点的字符串值,属于两次独立的消费操作,违反了流处理规则。

解决方法是先将节点的字符串值缓存到变量中,后续操作均使用该变量,确保只消费节点一次:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="3.0" exclude-result-prefixes="#all">
   <xsl:output method="xml" omit-xml-declaration="no" indent="yes" />
   <xsl:mode streamable="yes" />
    <xsl:template match="List/RequestP/ManNumber">
        <!-- 缓存节点字符串值,仅消费节点一次 -->
        <xsl:variable name="manNumValue" select="string(.)"/>
        <ManNumber>
           <xsl:value-of select="replace($manNumValue, '_BE', '')" />
        </ManNumber>  
        <xsl:if test="contains($manNumValue, '_BE')">
         <ManDescrip>BE</ManDescrip>
        </xsl:if>
   </xsl:template>
</xsl:stylesheet>

原理说明

通过xsl:variable将节点的字符串值提取并缓存后,后续的replace和contains操作都基于变量值进行,不再重复读取源节点内容,符合XSLT 3.0流处理的“单次消费”要求,从而解决报错问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 21:20:33