XSLT日期范围到每天

时间:2018-05-09 13:16:10

标签: xml xslt xsd

我想在xslt上寻求您的专业知识。 我有XML的日期范围,例如

=

现在我需要每个日期发送1行,例如对于ABC1 id,我需要以startdate enddate作为增量发送10条记录。

转换后,数据应如下所示

<data>
<ID>ABC1</ID>
<Start_Date>2018-05-01</Start_Date>
<End_Date>2018-05-10</End_Date>
<data>
<ID>ABC2</ID>
<Start_Date>2018-05-10</Start_Date>
<End_Date>2018-05-12</End_Date>
<data>
<root>

直到ABC1这样的总数我们需要有10个数据部分和ABC2 2数据部分。

请指导我如何在XSLT中实现逻辑。

1 个答案:

答案 0 :(得分:1)

正如您所说,您至少可以使用XSLT 2,您可以利用xs:date数据类型和算法操作(如减法XSLT / XPath 2及更高版本)支持计算天数差异,然后处理每个项目正确日期的时间:

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

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

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="data">
      <xsl:variable name="data" select="."/>
      <xsl:for-each select="0 to days-from-duration(xs:date(End_Date) - xs:date(Start_Date))">
          <xsl:apply-templates select="$data" mode="increment">
              <xsl:with-param name="date" tunnel="yes" select="xs:date($data/Start_Date) + xs:dayTimeDuration('P1D') * ."/>
          </xsl:apply-templates>
      </xsl:for-each>
  </xsl:template>

  <xsl:template match="data/Start_Date | data/End_Date" mode="increment">
      <xsl:param name="date" tunnel="yes"/>
      <xsl:copy>
          <xsl:value-of select="$date"/>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

这是XSLT 3,但仅适用于您可以用

替换XSLT 2的xsl:mode内容
<xsl:template match="@* | node()" mode="#default increment">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()" mode="#current"/>
  </xsl:copy>
</xsl:template>

https://xsltfiddle.liberty-development.net/gWmuiJ6的XSLT 3在线示例。