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

XSLT分组逻辑修正:K18/P01分组及无TP1的P01保留问题

修正XSLT以保留无TP1的P01节点并实现指定分组逻辑

需求概述

  • 对K18节点按ALF和OND字段分组,同组节点的P04Y、P04Z、P04、P03子段按P04Y→P04Z→P04→P03的顺序合并(所有子段均为非必填)
  • 对P01节点下的TP1子节点按ID和RAS字段分组,将同组的PT2子段合并到同一个TP1节点下;若P01无TP1子节点,需原样保留该P01节点(TP1为非必填)

问题

当前使用的XSLT会删除不含TP1子节点的P01节点,需要修正该问题,同时确保上述两项分组逻辑正确执行。

输入示例

<Root>
  <K18 ALF="A" OND="1">
    <P04Y>Y1</P04Y>
    <P03>3A1</P03>
  </K18>
  <K18 ALF="A" OND="1">
    <P04Z>Z1</P04Z>
    <P04>4A1</P04>
  </K18>
  <P01>
    <SomeData>Data1</SomeData>
    <!-- 无TP1节点 -->
  </P01>
  <P01>
    <TP1 ID="T1" RAS="R1">
      <PT2>PT2-1</PT2>
    </TP1>
    <TP1 ID="T1" RAS="R1">
      <PT2>PT2-2</PT2>
    </TP1>
  </P01>
</Root>

期望输出

<Root>
  <K18 ALF="A" OND="1">
    <P04Y>Y1</P04Y>
    <P04Z>Z1</P04Z>
    <P04>4A1</P04>
    <P03>3A1</P03>
  </K18>
  <P01>
    <SomeData>Data1</SomeData>
  </P01>
  <P01>
    <TP1 ID="T1" RAS="R1">
      <PT2>PT2-1</PT2>
      <PT2>PT2-2</PT2>
    </TP1>
  </P01>
</Root>

现有问题XSLT

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

  <!-- 分组处理K18 -->
  <xsl:template match="K18">
    <xsl:for-each-group select="." group-by="concat(ALF, '|', OND)">
      <K18 ALF="{current-grouping-key()}" OND="{current-grouping-key()}">
        <xsl:copy-of select="current-group()/P04Y"/>
        <xsl:copy-of select="current-group()/P04Z"/>
        <xsl:copy-of select="current-group()/P04"/>
        <xsl:copy-of select="current-group()/P03"/>
      </K18>
    </xsl:for-each-group>
  </xsl:template>

  <!-- 仅处理含TP1的P01 -->
  <xsl:template match="P01[TP1]">
    <P01>
      <xsl:copy-of select="*[not(self::TP1)]"/>
      <xsl:for-each-group select="TP1" group-by="concat(ID, '|', RAS)">
        <TP1 ID="{ID}" RAS="{RAS}">
          <xsl:copy-of select="current-group()/PT2"/>
        </TP1>
      </xsl:for-each-group>
    </P01>
  </xsl:template>
</xsl:stylesheet>

修正后的XSLT

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

  <!-- 默认身份模板:保留所有未自定义匹配的节点/属性 -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- 分组处理K18节点 -->
  <xsl:template match="K18">
    <xsl:for-each-group select="." group-by="concat(ALF, '|', OND)">
      <K18 
        ALF="{substring-before(current-grouping-key(), '|')}" 
        OND="{substring-after(current-grouping-key(), '|')}"
      >
        <!-- 按指定顺序合并子段 -->
        <xsl:copy-of select="current-group()/P04Y"/>
        <xsl:copy-of select="current-group()/P04Z"/>
        <xsl:copy-of select="current-group()/P04"/>
        <xsl:copy-of select="current-group()/P03"/>
      </K18>
    </xsl:for-each-group>
  </xsl:template>

  <!-- 处理所有P01节点(含无TP1的情况) -->
  <xsl:template match="P01">
    <P01>
      <!-- 复制除TP1外的所有子节点 -->
      <xsl:copy-of select="*[not(self::TP1)]"/>
      <!-- 仅当存在TP1时执行分组逻辑 -->
      <xsl:if test="TP1">
        <xsl:for-each-group select="TP1" group-by="concat(ID, '|', RAS)">
          <TP1 
            ID="{substring-before(current-grouping-key(), '|')}" 
            RAS="{substring-after(current-grouping-key(), '|')}"
          >
            <xsl:copy-of select="current-group()/PT2"/>
          </TP1>
        </xsl:for-each-group>
      </xsl:if>
    </P01>
  </xsl:template>
</xsl:stylesheet>

关键修改说明

  1. 添加默认身份模板:确保所有未被自定义模板匹配的节点(包括无TP1的P01)都会被原样保留,避免被XSLT默认模板跳过。
  2. 调整P01匹配范围:将模板匹配条件从P01[TP1]改为P01,覆盖所有P01节点;通过<xsl:if test="TP1">仅在存在TP1时执行分组逻辑,无TP1时直接复制其他子节点。
  3. 修正K18属性赋值:原代码错误地将完整分组键赋值给ALF和OND,修正为用substring-before和substring-after拆分分组键,正确提取原始字段值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 20:13:18