XSLT - 如何为两个日期之间的每个日期创建一个元素

XSLT - How do I Create an Element for Each Date Between Two Dates

我正在使用以下 XML 结构。

<File>
<Record>
    <ID>01234</ID>
    <Description>Sample description</Description>
    <StartDate>2021-01-29</StartDate>
    <EndDate>2021-02-02</EndDate>
</Record>
<Record>
    <ID>56789</ID>
    <Description>Sample description</Description>
    <StartDate>2021-02-03</StartDate>
    <EndDate>2021-02-06</EndDate>
</Record>

我需要为给定 StartDate 和 EndDate 之间的每个日期创建一个 Record 元素,包括给定的 StartDate 和 EndDate。我的结果 XML 需要如下所示。

<File>
<Record>
    <ID>01234</ID>
    <Description>Sample description</Description>
    <EventDate>2021-01-29</EventDate>
</Record>
<Record>
    <ID>01234</ID>
    <Description>Sample description</Description>
    <EventDate>2021-01-30</EventDate>
</Record>
<Record>
    <ID>01234</ID>
    <Description>Sample description</Description>
    <EventDate>2021-01-31</EventDate>
</Record>
<Record>
    <ID>01234</ID>
    <Description>Sample description</Description>
    <EventDate>2021-02-01</EventDate>
</Record>
<Record>
    <ID>01234</ID>
    <Description>Sample description</Description>
    <EventDate>2021-02-02</EventDate>
</Record>
<Record>
    <ID>56789</ID>
    <Description>Sample description</Description>
    <EventDate>2021-02-03</EventDate>
</Record>
<Record>
    <ID>56789</ID>
    <Description>Sample description</Description>
    <EventDate>2021-02-04</EventDate>
</Record>
<Record>
    <ID>56789</ID>
    <Description>Sample description</Description>
    <EventDate>2021-02-05</EventDate>
</Record>
<Record>
    <ID>56789</ID>
    <Description>Sample description</Description>
    <EventDate>2021-02-06</EventDate>
</Record>

到目前为止,我所做的研究并没有给我太多帮助,鉴于我严重缺乏 XSLT 知识,我将不胜感激任何帮助。我的偏好是不使用递归函数(可能是 XSLT 3.0??),但在这一点上我会使用任何东西。

谢谢。

可以通过以下方式完成:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:output method="xml"/>

  <xsl:template match="Record">
    <xsl:variable name="currentRec" select="."/>
    <xsl:variable name="numberDays" select="xs:integer((xs:date(EndDate) - xs:date(StartDate)) div xs:dayTimeDuration('P1D'))"/>
    <xsl:for-each select="0 to $numberDays">
        <Record>
            <xsl:copy-of select="$currentRec/ID"/>
            <xsl:copy-of select="$currentRec/Description"/>
            <EventDate><xsl:value-of select="xs:date($currentRec/StartDate) + (xs:dayTimeDuration('P1D')*(position()-1))"/></EventDate>
        </Record>
    </xsl:for-each>
  </xsl:template>
  
</xsl:stylesheet>

看到它在这里工作:https://xsltfiddle.liberty-development.net/ei5R4uW/1

你可以使用

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    expand-text="yes"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>
  
  <xsl:output indent="yes"/>

  <xsl:template match="Record">
      <xsl:apply-templates select="(0 to days-from-duration(xs:date(EndDate) - xs:date(StartDate))) ! current()" mode="split"/>
  </xsl:template>
  
  <xsl:template match="Record" mode="split">
      <xsl:copy>
          <xsl:apply-templates select="* except (StartDate, EndDate)"/>
          <EventDate>{xs:date(StartDate) + xs:dayTimeDuration('P1D') * (position() - 1)}</EventDate>
      </xsl:copy>
  </xsl:template>
  
</xsl:stylesheet>