XSLT 2.0节点树添加节点丢失父节点问题求助
解决XSL 2.0添加节点时丢失上层父节点的问题
嗨,我明白你的问题啦——你当前的模板只处理了<node>的子节点,完全没把<node>这个父容器复制进去,所以结果里才会少了外层的节点。咱们调整一下模板逻辑,就能保留完整的节点树了。
问题根源
你当前的模板匹配的是node()/*,也就是直接匹配<node>下面的子元素,模板执行时只会输出这些子元素,根本没处理上层的<node>节点。要保留完整结构,得先复制父节点,再在父节点内部处理子元素的添加操作。
修正后的完整代码
<xsl:variable name="A"> <node> <node1>ABC</node1> <node2>DEF</node2> <node4>KLM</node4> </node> </xsl:variable> <!-- 模板调用保持不变 --> <xsl:apply-templates select="$A" mode="copy"> <xsl:with-param name="ValueOfTheNode" select="'HIJ'"/> </xsl:apply-templates> <!-- 第一步:匹配顶层的<node>节点,复制它并处理内部子节点 --> <xsl:template match="node" mode="copy"> <xsl:param name="ValueOfTheNode"/> <!-- 复制当前的<node>父节点 --> <xsl:copy> <!-- 在<node>内部应用模板处理所有子节点,传递参数 --> <xsl:apply-templates select="*" mode="copy"> <xsl:with-param name="ValueOfTheNode" select="$ValueOfTheNode"/> </xsl:apply-templates> </xsl:copy> </xsl:template> <!-- 第二步:处理<node>下的子元素,实现添加node3的逻辑 --> <xsl:template match="*" mode="copy"> <xsl:param name="ValueOfTheNode"/> <!-- 复制当前子节点 --> <xsl:copy-of select="."/> <!-- 当节点是node2时,添加新的node3 --> <xsl:if test="local-name() = 'node2'"> <node3> <xsl:value-of select="$ValueOfTheNode"/> </node3> </xsl:if> </xsl:template>
代码关键点说明
- 新增的第一个模板专门匹配
<node>节点,用<xsl:copy>复制这个父容器,然后在容器内部调用子节点的处理模板,这样外层的<node>就被保留下来了。 - 第二个模板负责处理子元素,逻辑和你原来的差不多,但匹配范围调整为
*(所有元素节点),确保能处理<node>下的所有子节点。 - 用
local-name()代替name()是更稳妥的写法,避免后续如果XML添加命名空间时出现匹配问题。
运行结果
执行修正后的代码后,就能得到你想要的完整节点树:
<node> <node1>ABC</node1> <node2>DEF</node2> <node3>HIJ</node3> <node4>KLM</node4> </node>
内容的提问来源于stack exchange,提问作者Farolink
相关产品推荐
相关产品推荐

