在xslt中按连续日期分组并按相似日期求和

在xslt中按连续日期分组并按相似日期求和,xslt,xslt-2.0,Xslt,Xslt 2.0,大师 我尝试按连续日期打印数据行,并将每行中所有休假单位的总和按一个汇总行打印,开始日期为休假的第一天,结束日期为连续组中最后一次休假。我使用了下面的xslt,它工作得很好,但是可能在系统中取消了休假,那么在同一天,我可以得到一个负值,在这种情况下,我下面的xslt无法工作,因为我无法处理类似的日期和类似的类型场景。有什么建议吗 XML 我期望的输出如下: 12,Compassionate Leave,2018-02-01,2018-02-01,1 12,Compassionate Leave,

大师 我尝试按连续日期打印数据行,并将每行中所有休假单位的总和按一个汇总行打印,开始日期为休假的第一天,结束日期为连续组中最后一次休假。我使用了下面的xslt,它工作得很好,但是可能在系统中取消了休假,那么在同一天,我可以得到一个负值,在这种情况下,我下面的xslt无法工作,因为我无法处理类似的日期和类似的类型场景。有什么建议吗

XML

我期望的输出如下:

12,Compassionate Leave,2018-02-01,2018-02-01,1
12,Compassionate Leave,2018-02-08,2018-02-08,1
12,Compassionate Leave,2018-02-08,2018-02-09,0
12,Statutory Holiday,2018-02-06,2018-02-07,2
12,Compassionate Leave,2018-02-01,2018-02-01,1
12,Compassionate Leave,2018-02-08,2018-02-09,1
12,Statutory Holiday,2018-02-06,2018-02-07,2

您已经发布了一个XSLT 3样式表,因此我想虽然您将问题标记为XSLT 2,但使用XSLT 3是可以的,因此这里有一个使用
xsl:iterate
的建议:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:mf="http://example.com/mf"
    exclude-result-prefixes="xs mf"
    version="3.0">

  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:function name="mf:date" as="xs:date">
      <xsl:param name="input" as="xs:string"/>
      <xsl:sequence select="xs:date(substring($input, 1, 10))"/>
  </xsl:function>

  <xsl:function name="mf:line" as="xs:string">
      <xsl:param name="group" as="element(Time_Off)*"/>
      <xsl:value-of 
        select="$group[1]/../Worker_ID, 
                $group[1]/Type, 
                mf:date($group[1]/Date),
                mf:date($group[last()]/Date),
                sum($group/Units)"
                separator=","/>      
  </xsl:function>

  <xsl:template match="Worker">
      <xsl:for-each-group select="Time_Off" group-by="Type">
          <xsl:variable name="sorted-times" as="element(Time_Off)*">
              <xsl:perform-sort select="current-group()">
                  <xsl:sort select="mf:date(Date)"/>
              </xsl:perform-sort>
          </xsl:variable>
          <xsl:iterate select="$sorted-times">
              <xsl:param name="group" as="element(Time_Off)*" select="()"/>
              <xsl:on-completion>
                 <xsl:value-of select="mf:line($group), ''" separator="&#10;"/> 
              </xsl:on-completion>
              <xsl:variable name="new-group" as="xs:boolean"
                select="$group 
                   and mf:date(Date) - mf:date($group[last()]/Date) gt xs:dayTimeDuration('P1D')"/>
              <xsl:if test="$new-group">
                  <xsl:value-of select="mf:line($group), ''" separator="&#10;"/>
              </xsl:if>
              <xsl:next-iteration>
                  <xsl:with-param name="group" select="if ($new-group) then . else ($group, .)"/>
              </xsl:next-iteration>
          </xsl:iterate>
      </xsl:for-each-group>
  </xsl:template>

</xsl:stylesheet>


在线。

Nice迭代方法。
12,Compassionate Leave,2018-02-01,2018-02-01,1
12,Compassionate Leave,2018-02-08,2018-02-09,1
12,Statutory Holiday,2018-02-06,2018-02-07,2
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:mf="http://example.com/mf"
    exclude-result-prefixes="xs mf"
    version="3.0">

  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:function name="mf:date" as="xs:date">
      <xsl:param name="input" as="xs:string"/>
      <xsl:sequence select="xs:date(substring($input, 1, 10))"/>
  </xsl:function>

  <xsl:function name="mf:line" as="xs:string">
      <xsl:param name="group" as="element(Time_Off)*"/>
      <xsl:value-of 
        select="$group[1]/../Worker_ID, 
                $group[1]/Type, 
                mf:date($group[1]/Date),
                mf:date($group[last()]/Date),
                sum($group/Units)"
                separator=","/>      
  </xsl:function>

  <xsl:template match="Worker">
      <xsl:for-each-group select="Time_Off" group-by="Type">
          <xsl:variable name="sorted-times" as="element(Time_Off)*">
              <xsl:perform-sort select="current-group()">
                  <xsl:sort select="mf:date(Date)"/>
              </xsl:perform-sort>
          </xsl:variable>
          <xsl:iterate select="$sorted-times">
              <xsl:param name="group" as="element(Time_Off)*" select="()"/>
              <xsl:on-completion>
                 <xsl:value-of select="mf:line($group), ''" separator="&#10;"/> 
              </xsl:on-completion>
              <xsl:variable name="new-group" as="xs:boolean"
                select="$group 
                   and mf:date(Date) - mf:date($group[last()]/Date) gt xs:dayTimeDuration('P1D')"/>
              <xsl:if test="$new-group">
                  <xsl:value-of select="mf:line($group), ''" separator="&#10;"/>
              </xsl:if>
              <xsl:next-iteration>
                  <xsl:with-param name="group" select="if ($new-group) then . else ($group, .)"/>
              </xsl:next-iteration>
          </xsl:iterate>
      </xsl:for-each-group>
  </xsl:template>

</xsl:stylesheet>