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
相关产品推荐
相关产品推荐

