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

XSLT多数组按年月分组排序问题求助

解决方案:跨数组按年月分组整合

核心思路

先合并所有数组中的目标条目,再通过统一的年月标识分组,最后跨数组提取对应年月的数据并排序输出。


1. 基于XSLT 2.0+的实现方案(推荐)

XSLT 2.0及以上的<xsl:for-each-group>可以直接实现分组逻辑,代码更简洁:

完整XSLT代码

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

  <xsl:template match="/">
    <result>
      <!-- 合并所有数组的item节点 -->
      <xsl:variable name="allItems" select="root/*/item"/>

      <!-- 按格式化后的年月分组(确保月份为两位数字,避免排序混乱) -->
      <xsl:for-each-group select="$allItems" group-by="concat(year, '-', format-number(month, '00'))">
        <!-- 按年份、月份数值排序 -->
        <xsl:sort select="year" data-type="number"/>
        <xsl:sort select="month" data-type="number"/>

        <group>
          <!-- 输出年月信息 -->
          <year><xsl:value-of select="current-group()/year[1]"/></year>
          <month><xsl:value-of select="current-group()/month[1]"/></month>

          <!-- 从array1提取对应年月的数据 -->
          <value1>
            <xsl:value-of select="$allItems[year=current-group()/year[1] and month=current-group()/month[1] and parent::array1]/value"/>
          </value1>

          <!-- 从array2提取对应年月的数据 -->
          <value2>
            <xsl:value-of select="$allItems[year=current-group()/year[1] and month=current-group()/month[1] and parent::array2]/value"/>
          </value2>
        </group>
      </xsl:for-each-group>
    </result>
  </xsl:template>
</xsl:stylesheet>

2. 兼容XSLT 1.0的Muenchian分组方案

如果只能使用XSLT 1.0,通过Muenchian分组实现:

完整XSLT代码

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

  <!-- 定义年月分组的键(补全月份为两位数字) -->
  <xsl:key name="monthGroup" match="item" use="concat(year, '-', substring('00', 1, 2 - string-length(month)), month)"/>

  <xsl:template match="/">
    <result>
      <xsl:variable name="allItems" select="root/*/item"/>

      <!-- 筛选唯一的年月分组 -->
      <xsl:for-each select="$allItems[generate-id()=generate-id(key('monthGroup', concat(year, '-', substring('00', 1, 2 - string-length(month)), month))[1])]">
        <!-- 按年份、月份数值排序 -->
        <xsl:sort select="year" data-type="number"/>
        <xsl:sort select="month" data-type="number"/>

        <group>
          <year><xsl:value-of select="year"/></year>
          <month><xsl:value-of select="month"/></month>

          <!-- 从array1提取数据 -->
          <value1>
            <xsl:value-of select="key('monthGroup', concat(year, '-', substring('00', 1, 2 - string-length(month)), month))[parent::array1]/value"/>
          </value1>

          <!-- 从array2提取数据 -->
          <value2>
            <xsl:value-of select="key('monthGroup', concat(year, '-', substring('00', 1, 2 - string-length(month)), month))[parent::array2]/value"/>
          </value2>
        </group>
      </xsl:for-each>
    </result>
  </xsl:template>
</xsl:stylesheet>

3. 关键注意事项

  • 年月格式化:必须将月份补全为两位数字(如01而非1),否则字符串排序时会出现10排在2前面的错误。
  • 跨数组匹配:通过parent::数组节点名区分不同数据源的条目,确保提取对应数组的数据。
  • 数值排序:排序时指定data-type="number",避免按字符串顺序排序导致的年月混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 20:22:43