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

如何用XSLT处理重复ReplyDTO节点,获取最新estimateNo

Solution to Deduplicate ReplyDTO by estimateNo (Keep Latest by Date/Time)

To solve this problem, we need to group ReplyDTO elements by their estimateNo, then retain only the entry with the most recent creationDate and creationTime for each group. Below are solutions for both XSLT 2.0+ (simpler) and XSLT 1.0 (compatible with older processors).


XSLT 2.0+ Solution

This uses xsl:for-each-group for straightforward grouping, and leverages string concatenation of date/time to find the latest entry (since YYYYMMDDHHMMSS is lexicographically sortable).

<xsl:stylesheet version="2.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ns1="http://some.url">
  <xsl:output method="xml" indent="yes"/>
  
  <!-- Identity template: copies all content by default -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  
  <!-- Process the parent element of ReplyDTO -->
  <xsl:template match="replyelement">
    <xsl:copy>
      <!-- Group ReplyDTO elements by estimateNo -->
      <xsl:for-each-group select="ns1:ReplyDTO" group-by="ns1:estimateNo">
        <!-- Select the entry with the latest creationDate + creationTime -->
        <xsl:sequence select="current-group()[
          concat(ns1:creationDate, ns1:creationTime) = max(current-group()/concat(ns1:creationDate, ns1:creationTime))
        ]"/>
      </xsl:for-each-group>
      <!-- Copy any non-ReplyDTO child elements from the original -->
      <xsl:apply-templates select="node()[not(self::ns1:ReplyDTO)]"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

How it works:

  1. Identity Template: Preserves all elements and attributes except where we explicitly override behavior.
  2. Grouping: xsl:for-each-group clusters ReplyDTO elements by their estimateNo value.
  3. Select Latest Entry: For each group, we compare the concatenated creationDate + creationTime string (e.g., 20160404143000) and select the entry where this string equals the maximum value in the group (which corresponds to the most recent timestamp).

XSLT 1.0 Solution

If you're limited to XSLT 1.0, use Muenchian grouping to group elements, then sort to find the latest entry.

<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ns1="http://some.url">
  <xsl:output method="xml" indent="yes"/>
  
  <!-- Key to group ReplyDTO elements by estimateNo -->
  <xsl:key name="replyByEstimateNo" match="ns1:ReplyDTO" use="ns1:estimateNo"/>
  
  <!-- Identity template -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  
  <!-- Process the parent element of ReplyDTO -->
  <xsl:template match="replyelement">
    <xsl:copy>
      <!-- Iterate over unique estimateNo groups -->
      <xsl:for-each select="ns1:ReplyDTO[generate-id() = generate-id(key('replyByEstimateNo', ns1:estimateNo)[1])]">
        <!-- Get all entries in the current estimateNo group -->
        <xsl:variable name="currentGroup" select="key('replyByEstimateNo', ns1:estimateNo)"/>
        
        <!-- Sort group by concatenated date/time (descending) and pick the first entry -->
        <xsl:for-each select="$currentGroup">
          <xsl:sort select="concat(ns1:creationDate, ns1:creationTime)" order="descending"/>
          <xsl:if test="position() = 1">
            <xsl:copy-of select="."/>
          </xsl:if>
        </xsl:for-each>
      </xsl:for-each>
      <!-- Copy non-ReplyDTO child elements -->
      <xsl:apply-templates select="node()[not(self::ns1:ReplyDTO)]"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

How it works:

  1. Muenchian Grouping: A key is defined to group ReplyDTO elements by estimateNo. We then select only the first element of each unique group using generate-id.
  2. Sorting: For each group, we sort entries by the concatenated creationDate + creationTime in descending order, then copy only the first entry (the latest one).

Notes:

  • Namespace Handling: Ensure the ns1 namespace in the XSLT matches the one in your input XML.
  • Time Format: This solution assumes creationTime is in a sortable format like HHMMSS (no colons). If your time includes separators (e.g., 14:30:00), you'll need to normalize it first (e.g., using translate(ns1:creationTime, ':', '') to remove colons).
  • Ties: If multiple entries in a group have the same latest timestamp, the XSLT 2.0 solution will retain all of them. To keep only one, add [1] to the end of the xsl:sequence select. The XSLT 1.0 solution already keeps only the first sorted entry.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:13:50