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

XSLT处理XML时文本注入异常及元素重复生成需求咨询

问题与解决方案

问题描述

使用给定的XSLT处理XML配置时,保留<xsl:strip-space elements="*"/>标签会导致输出出现非法文本拼接;移除该标签后输出恢复正常,但需要在保留空格处理的前提下,实现指定propertyDescriptor元素重复生成+每个元素的name唯一的需求。

原因分析

原XSLT的核心问题在于append_name模板中的<xsl:value-of select="node()"/>:当处理包含子元素的节点时,node()会选中所有子节点(包括元素节点),xsl:value-of会直接将这些节点的文本值拼接输出,导致元素被错误转成文本串混入结果。同时,new-descriptor模板通过for-each遍历所有节点的逻辑,也容易引发节点处理顺序和类型的错误。

修复后的XSLT代码

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes" standalone="yes"/>
    <xsl:strip-space elements="*"/>

    <!-- 默认复制模板:复制所有未被特殊匹配的节点和属性 -->
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <!-- 匹配目标propertyDescriptor,触发重复生成逻辑 -->
    <xsl:template match="propertyDescriptor[name='enable_decline_rule']">
        <!-- 修改total参数可调整重复次数,当前设置为2 -->
        <xsl:call-template name="repeat-generator">
            <xsl:with-param name="total" select="2"/>
            <xsl:with-param name="current" select="1"/>
        </xsl:call-template>
    </xsl:template>

    <!-- 递归生成重复的propertyDescriptor元素 -->
    <xsl:template name="repeat-generator">
        <xsl:param name="total"/>
        <xsl:param name="current"/>
        
        <xsl:if test="$current <= $total">
            <propertyDescriptor>
                <!-- 对原节点的所有子元素应用模板,传递当前序号作为后缀 -->
                <xsl:apply-templates select="*">
                    <xsl:with-param name="suffix" select="$current"/>
                </xsl:apply-templates>
            </propertyDescriptor>
            <!-- 递归调用生成下一个元素 -->
            <xsl:call-template name="repeat-generator">
                <xsl:with-param name="total" select="$total"/>
                <xsl:with-param name="current" select="$current + 1"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <!-- 处理带repeat属性的name元素,添加序号后缀 -->
    <xsl:template match="name[@repeat]">
        <xsl:param name="suffix"/>
        <name>
            <xsl:value-of select="concat(., '_', $suffix)"/>
        </name>
    </xsl:template>

    <!-- 处理其他元素,传递后缀参数给子节点,确保嵌套的name也能被重命名 -->
    <xsl:template match="*[not(self::name[@repeat])]">
        <xsl:param name="suffix"/>
        <xsl:copy>
            <xsl:apply-templates select="node()|@*">
                <xsl:with-param name="suffix" select="$suffix"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

修复说明

  • 移除了原代码中容易引发错误的new-descriptor和append_name模板,改用XSLT标准的模板匹配机制,逻辑更清晰稳定
  • repeat-generator模板通过递归实现指定次数的元素生成,参数total控制重复次数
  • 单独匹配带@repeat属性的name元素,通过concat拼接序号后缀,确保name唯一
  • 其他元素模板负责传递suffix参数,保证嵌套的propertyDescriptor中的name也能被正确重命名
  • 保留了<xsl:strip-space elements="*"/>,有效处理XML中的空白节点,同时不会产生非法文本拼接

验证结果

使用修复后的XSLT处理原始XML,将生成符合需求的输出:两个完整的propertyDescriptor元素,各自的name(包括嵌套的decline_rule_identifier)均添加了正确的序号后缀,无非法文本注入问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 20:42:32