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

XSLT accumulator如何累积元素引用 保留元素属性及文本

问题原因
  • 现有累加器声明的存储类型为xs:string*(字符串序列),匹配authorialNote节点时通过@marker || .做了字符串拼接,直接将节点转换为拼接后的纯文本,完全丢弃了原节点的属性、子元素结构,自然无法保留完整节点信息
  • 输出模板中使用xsl:value-of仅能提取节点的文本值,同时eId="@eId"是硬编码的固定字符串,无法读取原节点上的真实eId属性值
正确实现方案

核心思路是将累加器的存储类型改为元素节点序列,直接存储匹配到的authorialNote节点引用,不做任何字符串转换,输出时直接读取节点的属性、复制节点结构即可。

注意:XSLT 3.0累加器需要显式声明启用,请在<xsl:stylesheet>根节点下添加<xsl:use-accumulators name="authorialNote_accumulator"/>,否则累加器不会生效。

1. 修正后的累加器代码

<xsl:output omit-xml-declaration="no" indent="yes"/>
<!-- 累加器类型改为元素节点序列,初始值为空序列 -->
<xsl:accumulator name="authorialNote_accumulator" as="element()*" initial-value="()">
    <!-- 匹配到authorialNote时,直接将当前节点追加到累积序列中,不做字符串转换 -->
    <xsl:accumulator-rule match="authorialNote" select="$value, ."/>
    <!-- 匹配到eop结束阶段时清空累加器,为下一段内容的累积做准备 -->
    <xsl:accumulator-rule match="eop" select="()" phase="end"/>
</xsl:accumulator>

2. 修正后的eop节点匹配模板

<xsl:template match="eop">
    <xsl:variable name="_authorialNote" select="accumulator-before('authorialNote_accumulator')"/>
    <div class="authorial-note">
        <xsl:for-each select="$_authorialNote">
            <!-- 通过属性值模板读取当前节点的真实eId属性 -->
            <div eId="{@eId}">
                <!-- 复制当前节点下所有子元素、文本、结构,完整保留原内容 -->
                <xsl:copy-of select="node()"/>
                <!-- 如果需要连同authorialNote标签本身、其所有属性一起完整输出,直接替换为<xsl:copy-of select="."/>即可 -->
            </div>
        </xsl:for-each>
    </div>
</xsl:template>
关键逻辑说明
  • 累加器存储element()*类型的节点序列时,保存的是源文档中对应节点的引用,不会丢失节点的任何属性、子元素、文本结构信息
  • 需要读取节点属性作为输出属性值时,要使用属性值模板{@属性名}的写法,直接将属性名写在引号内只会输出固定字符串,不会读取节点属性
  • 如果输出不需要额外包裹自定义div层,直接在循环里写<xsl:copy-of select="."/>就能1:1还原原authorialNote节点的全部内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:27:34