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

如何在XSL中除指定元素外将其余XML元素放入二级节点(非硬编码)

通用XSL解决方案:将可变标签包裹到Payload中

需求说明

  • 输入XML里<value>和<UniqueId>是固定存在的标签
  • 需要把<value>节点下除<UniqueId>之外的所有可变标签,统一放到<Payload>标签内部

输入XML

<value>
  <UniqueId>160052-ASDF</UniqueId>
  <ShipmentId>160052</ShipmentId>
  <PickListNo>160052_1</PickListNo>
</value>

期望输出XML

<value>
  <UniqueId>160052-ASDF</UniqueId>
  <Payload>
    <ShipmentId>160052</ShipmentId>
    <PickListNo>160052_1</PickListNo>
  </Payload>
</value>

现有硬编码XSL(不通用)

这种写法需要硬编码所有可变标签名,无法适配标签变化的场景:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <value>
    <UniqueId>
      <xsl:value-of select="/value/UniqueId"/>
    </UniqueId>
    <Payload>
      <ShipmentId>
        <xsl:value-of select="/value/ShipmentId"/>
      </ShipmentId>
      <PickListNo>
        <xsl:value-of select="/value/PickListNo"/>
      </PickListNo>
    </Payload>
  </value>
</xsl:template>
</xsl:stylesheet>

尝试的失败写法

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <value>
    <UniqueId>
      <xsl:value-of select="/value/UniqueId"/>
    </UniqueId>
    <Payload>
      <xsl:for-each select="*[not(self::UniqueId)]">
        <xsl:copy-of select="."/>
      </xsl:for-each>
    </Payload>
  </value>
</xsl:template>
</xsl:stylesheet>

失败原因:当前上下文是根节点/,*匹配的是根节点下的<value>节点,而非<value>内部的子节点,导致无法选中目标标签。

通用解决方案

方案一(推荐:更简洁直观)

直接匹配<value>节点,切换上下文后简化选择逻辑:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/value">
    <value>
      <!-- 直接复制原有的UniqueId标签及内容 -->
      <xsl:copy-of select="UniqueId"/>
      <!-- 创建Payload标签,复制所有非UniqueId的子节点 -->
      <Payload>
        <xsl:copy-of select="*[not(self::UniqueId)]"/>
      </Payload>
    </value>
  </xsl:template>
</xsl:stylesheet>

方案二(基于原写法修正路径)

在根节点匹配模板里,修正for-each的选择路径:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <value>
    <UniqueId>
      <xsl:value-of select="/value/UniqueId"/>
    </UniqueId>
    <Payload>
      <!-- 明确选择/value下的非UniqueId子节点 -->
      <xsl:for-each select="/value/*[not(self::UniqueId)]">
        <xsl:copy-of select="."/>
      </xsl:for-each>
    </Payload>
  </value>
</xsl:template>
</xsl:stylesheet>

两种方案都无需硬编码任何可变标签名,能自动适配<value>下除<UniqueId>外的所有子标签。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:30:21