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

XSLT实现父节点复制到子节点且不重复复制子节点

解决XML父节点内容复制到子节点(排除子节点本身)的XSLT问题

需求概述

需要将<FoodGroups>节点的内容(排除其下的<FoodGroup>子节点)复制到每个<FoodGroup>内部,同时重新组织XML结构。

原始XML输入

<FoodGroups>
   <Nutritional>Yes</Nutritional>
   <Artifical>No</Artificial>
   <FoodGroup>
      <Fruit>Grape</Fruit>
      <Fruit>Apple</Fruit>
   </FoodGroup>
   <FoodGroup>
      <Vegetable>Carrot</Vegetable>
      <Vegetable>Potato</Vegetable>
   </FoodGroup>
</FoodGroups>

期望输出XML

<xml>
   <FoodGroup>
      <Fruit>Grape</Fruit>
      <Fruit>Apple</Fruit>
      <FoodGroups>
         <Nutritional>Yes</Nutritional>
         <Artificial>No</Artificial>
      </FoodGroups>
   </FoodGroup>
   <FoodGroup>
      <Vegetable>Carrot</Vegetable>
      <Vegetable>Potato</Vegetable>
      <FoodGroups>
         <Nutritional>Yes</Nutritional>
         <Artificial>No</Artificial>
      </FoodGroups>
   </FoodGroup>
</xml>

原代码错误分析

你之前的XSLT代码存在两个核心问题:

  1. 筛选<FoodGroups>子节点的逻辑错误://FoodGroups/*[not(child::FoodGroup)]的含义是选择所有没有<FoodGroup>子元素的节点,但实际上我们需要排除的是<FoodGroups>下直接的<FoodGroup>节点本身,而非节点内容里包含<FoodGroup>的元素。
  2. 没有将筛选后的节点重新包裹在<FoodGroups>标签内,导致输出结构不符合预期。

修正后的XSLT代码

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="msxsl">
<xsl:output omit-xml-declaration="yes"
method="xml"
indent="yes"/>

<!-- 定义变量存储FoodGroups下的非FoodGroup子节点 -->
<xsl:variable name="foodGroupsMetadata" select="/FoodGroups/*[name() != 'FoodGroup']"/>

<xsl:template match="/">
<xml>
    <xsl:apply-templates select="/FoodGroups/FoodGroup"/>
</xml>
</xsl:template>

<xsl:template match="FoodGroup">
<FoodGroup>
    <!-- 复制当前FoodGroup的所有子节点 -->
    <xsl:copy-of select="./*"/>
    <!-- 重新创建FoodGroups节点并插入预存的元数据 -->
    <FoodGroups>
        <xsl:copy-of select="$foodGroupsMetadata"/>
    </FoodGroups>
</FoodGroup>
</xsl:template>

</xsl:stylesheet>

关键优化点

  • 使用变量$foodGroupsMetadata提前存储需要复制的元数据,避免重复查询,提升效率。
  • 筛选逻辑改为/FoodGroups/*[name() != 'FoodGroup'],精准排除<FoodGroups>下直接的<FoodGroup>子节点。
  • 手动创建<FoodGroups>标签并插入元数据,保证输出结构与预期一致。

处理多层嵌套场景

如果<FoodGroup>内部存在多层嵌套的子<FoodGroup>,该代码依然有效:因为我们的元数据变量仅筛选根<FoodGroups>下的非<FoodGroup>节点,不会影响内部嵌套的<FoodGroup>结构,只会将顶层元数据复制到每个最外层的<FoodGroup>中。

验证输出

运行修正后的XSLT,将得到与期望完全一致的XML结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 02:32:46