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

使用XSLT合并InterfaceHeader并按仓库排序XML节点

解决XML多节点合并与分组排序的XSLT实现

你有一段包含多个<InterfaceHeader>节点的XML,每个节点下的<Warehouse>分为WH1和WH2,且每个仓库对应固定的<LicenseNumber>与<GoodsOwnerId>。需要实现以下需求:

  • 将所有<InterfaceHeader>合并为单个节点
  • 按WH1在前、WH2在后的顺序排列仓库,同时把同仓库、同许可、同货主的<Item>合并到同一个<Warehouse>节点下

之前尝试的XSLT仅输出XML声明,无有效内容,下面是可行的实现方案:

输入XML示例

<Root>
  <InterfaceHeader>
    <Warehouse>WH2</Warehouse>
    <LicenseNumber>L2</LicenseNumber>
    <GoodsOwnerId>GO2</GoodsOwnerId>
    <Item>
      <ItemCode>ItemB1</ItemCode>
      <Qty>10</Qty>
    </Item>
  </InterfaceHeader>
  <InterfaceHeader>
    <Warehouse>WH1</Warehouse>
    <LicenseNumber>L1</LicenseNumber>
    <GoodsOwnerId>GO1</GoodsOwnerId>
    <Item>
      <ItemCode>ItemA1</ItemCode>
      <Qty>5</Qty>
    </Item>
  </InterfaceHeader>
  <InterfaceHeader>
    <Warehouse>WH1</Warehouse>
    <LicenseNumber>L1</LicenseNumber>
    <GoodsOwnerId>GO1</GoodsOwnerId>
    <Item>
      <ItemCode>ItemA2</ItemCode>
      <Qty>8</Qty>
    </Item>
  </InterfaceHeader>
  <InterfaceHeader>
    <Warehouse>WH2</Warehouse>
    <LicenseNumber>L2</LicenseNumber>
    <GoodsOwnerId>GO2</GoodsOwnerId>
    <Item>
      <ItemCode>ItemB2</ItemCode>
      <Qty>15</Qty>
    </Item>
  </InterfaceHeader>
</Root>

实现XSLT代码

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

  <!-- 定义分组键:Warehouse + LicenseNumber + GoodsOwnerId,确保同属性节点归为一组 -->
  <xsl:key name="warehouse-group" match="InterfaceHeader" 
           use="concat(Warehouse, '|', LicenseNumber, '|', GoodsOwnerId)"/>

  <xsl:template match="/Root">
    <!-- 生成单个合并后的InterfaceHeader节点 -->
    <InterfaceHeader>
      <!-- 筛选每个分组的首个节点,避免重复处理 -->
      <xsl:for-each select="InterfaceHeader[generate-id() = generate-id(key('warehouse-group', concat(Warehouse, '|', LicenseNumber, '|', GoodsOwnerId))[1])]">
        <!-- 按仓库名称排序,确保WH1优先 -->
        <xsl:sort select="Warehouse" order="ascending" case-order="upper-first"/>
        
        <!-- 输出仓库、许可、货主的固定信息 -->
        <Warehouse><xsl:value-of select="Warehouse"/></Warehouse>
        <LicenseNumber><xsl:value-of select="LicenseNumber"/></LicenseNumber>
        <GoodsOwnerId><xsl:value-of select="GoodsOwnerId"/></GoodsOwnerId>
        
        <!-- 遍历当前分组下的所有Item,合并到当前节点 -->
        <xsl:for-each select="key('warehouse-group', concat(Warehouse, '|', LicenseNumber, '|', GoodsOwnerId))/Item">
          <xsl:copy-of select="."/>
        </xsl:for-each>
      </xsl:for-each>
    </InterfaceHeader>
  </xsl:template>
</xsl:stylesheet>

关键逻辑说明

  • Muenchian分组:通过key定义唯一分组键,将属性完全相同的<InterfaceHeader>归为一组,避免重复输出仓库信息
  • 排序控制:用<xsl:sort>按仓库名称升序排列,保证WH1始终排在WH2之前
  • 节点合并:遍历每个分组的首个节点输出基础信息,再批量复制分组内所有<Item>到当前节点下,完成合并
  • 根节点处理:直接匹配根节点<Root>,生成单个<InterfaceHeader>作为最终输出容器

输出XML示例

<InterfaceHeader>
  <Warehouse>WH1</Warehouse>
  <LicenseNumber>L1</LicenseNumber>
  <GoodsOwnerId>GO1</GoodsOwnerId>
  <Item>
    <ItemCode>ItemA1</ItemCode>
    <Qty>5</Qty>
  </Item>
  <Item>
    <ItemCode>ItemA2</ItemCode>
    <Qty>8</Qty>
  </Item>
  <Warehouse>WH2</Warehouse>
  <LicenseNumber>L2</LicenseNumber>
  <GoodsOwnerId>GO2</GoodsOwnerId>
  <Item>
    <ItemCode>ItemB1</ItemCode>
    <Qty>10</Qty>
  </Item>
  <Item>
    <ItemCode>ItemB2</ItemCode>
    <Qty>15</Qty>
  </Item>
</InterfaceHeader>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 07:47:24