如何在 xslt 1.0 中执行 for 循环以输出 52 周日历而不考虑数据
How to do a for loop in xslt 1.0 to output a 52 week calendar irrespective of the data
我理解 XSLT1.0 的 for-each 循环的一些局限性。我需要一种将文件处理 52 次的方法,这样我就可以为一年中的 52 周中的每一周分配一个输出。该文件是一个简单的 Time Away From Work XML(每个节点都有日期/时间/代码等...)我需要每周包含该周预订的任何 TAFW 的记录,但我必须始终输出52节即使一周内没有数据。
数据将按日期排序,但我需要一种将其循环 52 次的方法。它必须始终是从上周算起的 52 周,所以它始终需要是相对的,否则我会在 XSLT 中创建一个临时 xml。
For-each 只有在超过 52 个节点时才有效,所以我不能使用它,因为可能不会超过 52 个节点。
原始数据
<Record>
<emp_number>73001486</emp_number>
<paycode>HOLIDAY</paycode>
<allday_flag>True</allday_flag>
<halfday_flag>False</halfday_flag>
<nethours>96.000</nethours>
<startdate_time>2021-12-14 00:00:00</startdate_time>
<enddate_time>2021-12-16 00:00:00</enddate_time>
</Record>
输出:
2021-12-06
2021-12-13
73001486,HOLIDAY,96
感谢收到任何想法!
更新:周开始是前一周,我可以从传递的信息中得出。总是整整几周。我不关心跨越数周的假期,我只关心 52 周内的 TAFW 开始日期(我很乐意推导)。
我认为你的问题应该分成几个独立的步骤 - 这些都不是微不足道的。
第一步是从给定的开始日期生成 52 周。嗯,实际上第一步是计算开始日期,但此时我不知道使用什么作为输入,所以让我们假设它是给定的:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
<output>
<xsl:call-template name="generate-weeks">
<xsl:with-param name="start-date" select="'2020-11-30'" />
<xsl:with-param name="n" select="52" />
</xsl:call-template>
</output>
</xsl:template>
<xsl:template name="generate-weeks">
<xsl:param name="start-date"/>
<xsl:param name="n" select="52"/>
<xsl:if test="$n > 0">
<week start-date="{$start-date}"/>
<xsl:call-template name="generate-weeks">
<xsl:with-param name="start-date">
<xsl:variable name="JDN">
<xsl:call-template name="JDN">
<xsl:with-param name="date" select="$start-date" />
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="GD">
<xsl:with-param name="JDN" select="$JDN + 7" />
</xsl:call-template>
</xsl:with-param>
<xsl:with-param name="n" select="$n - 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="JDN">
<xsl:param name="date"/>
<xsl:variable name="year" select="substring($date, 1, 4)"/>
<xsl:variable name="month" select="substring($date, 6, 2)"/>
<xsl:variable name="day" select="substring($date, 9, 2)"/>
<xsl:variable name="a" select="floor((14 - $month) div 12)"/>
<xsl:variable name="y" select="$year + 4800 - $a"/>
<xsl:variable name="m" select="$month + 12*$a - 3"/>
<xsl:value-of select="$day + floor((153*$m + 2) div 5) + 365*$y + floor($y div 4) - floor($y div 100) + floor($y div 400) - 32045" />
</xsl:template>
<xsl:template name="GD">
<xsl:param name="JDN"/>
<xsl:variable name="f" select="$JDN + 1401 + floor((floor((4 * $JDN + 274277) div 146097) * 3) div 4) - 38"/>
<xsl:variable name="e" select="4*$f + 3"/>
<xsl:variable name="g" select="floor(($e mod 1461) div 4)"/>
<xsl:variable name="h" select="5*$g + 2"/>
<xsl:variable name="D" select="floor(($h mod 153) div 5 ) + 1"/>
<xsl:variable name="M" select="(floor($h div 153) + 2) mod 12 + 1"/>
<xsl:variable name="Y" select="floor($e div 1461) - 4716 + floor((14 - $M) div 12)"/>
<xsl:value-of select="$Y" />
<xsl:value-of select="format-number($M, '-00')"/>
<xsl:value-of select="format-number($D, '-00')"/>
</xsl:template>
</xsl:stylesheet>
这将产生:
结果
<?xml version="1.0" encoding="utf-8"?>
<output>
<week start-date="2020-11-30"/>
<week start-date="2020-12-07"/>
<week start-date="2020-12-14"/>
<week start-date="2020-12-21"/>
<week start-date="2020-12-28"/>
<week start-date="2021-01-04"/>
<week start-date="2021-01-11"/>
<week start-date="2021-01-18"/>
<week start-date="2021-01-25"/>
<week start-date="2021-02-01"/>
<week start-date="2021-02-08"/>
<week start-date="2021-02-15"/>
<week start-date="2021-02-22"/>
<week start-date="2021-03-01"/>
<week start-date="2021-03-08"/>
<week start-date="2021-03-15"/>
<week start-date="2021-03-22"/>
<week start-date="2021-03-29"/>
<week start-date="2021-04-05"/>
<week start-date="2021-04-12"/>
<week start-date="2021-04-19"/>
<week start-date="2021-04-26"/>
<week start-date="2021-05-03"/>
<week start-date="2021-05-10"/>
<week start-date="2021-05-17"/>
<week start-date="2021-05-24"/>
<week start-date="2021-05-31"/>
<week start-date="2021-06-07"/>
<week start-date="2021-06-14"/>
<week start-date="2021-06-21"/>
<week start-date="2021-06-28"/>
<week start-date="2021-07-05"/>
<week start-date="2021-07-12"/>
<week start-date="2021-07-19"/>
<week start-date="2021-07-26"/>
<week start-date="2021-08-02"/>
<week start-date="2021-08-09"/>
<week start-date="2021-08-16"/>
<week start-date="2021-08-23"/>
<week start-date="2021-08-30"/>
<week start-date="2021-09-06"/>
<week start-date="2021-09-13"/>
<week start-date="2021-09-20"/>
<week start-date="2021-09-27"/>
<week start-date="2021-10-04"/>
<week start-date="2021-10-11"/>
<week start-date="2021-10-18"/>
<week start-date="2021-10-25"/>
<week start-date="2021-11-01"/>
<week start-date="2021-11-08"/>
<week start-date="2021-11-15"/>
<week start-date="2021-11-22"/>
</output>
下一步是预处理输入记录,并为每个记录分配一周开始日的值。然后可以通过匹配两个开始日期将每个记录分配给相应的周。我建议你问一个单独的问题(或问题)。
我理解 XSLT1.0 的 for-each 循环的一些局限性。我需要一种将文件处理 52 次的方法,这样我就可以为一年中的 52 周中的每一周分配一个输出。该文件是一个简单的 Time Away From Work XML(每个节点都有日期/时间/代码等...)我需要每周包含该周预订的任何 TAFW 的记录,但我必须始终输出52节即使一周内没有数据。 数据将按日期排序,但我需要一种将其循环 52 次的方法。它必须始终是从上周算起的 52 周,所以它始终需要是相对的,否则我会在 XSLT 中创建一个临时 xml。
For-each 只有在超过 52 个节点时才有效,所以我不能使用它,因为可能不会超过 52 个节点。
原始数据
<Record>
<emp_number>73001486</emp_number>
<paycode>HOLIDAY</paycode>
<allday_flag>True</allday_flag>
<halfday_flag>False</halfday_flag>
<nethours>96.000</nethours>
<startdate_time>2021-12-14 00:00:00</startdate_time>
<enddate_time>2021-12-16 00:00:00</enddate_time>
</Record>
输出:
2021-12-06
2021-12-13
73001486,HOLIDAY,96
感谢收到任何想法!
更新:周开始是前一周,我可以从传递的信息中得出。总是整整几周。我不关心跨越数周的假期,我只关心 52 周内的 TAFW 开始日期(我很乐意推导)。
我认为你的问题应该分成几个独立的步骤 - 这些都不是微不足道的。
第一步是从给定的开始日期生成 52 周。嗯,实际上第一步是计算开始日期,但此时我不知道使用什么作为输入,所以让我们假设它是给定的:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
<output>
<xsl:call-template name="generate-weeks">
<xsl:with-param name="start-date" select="'2020-11-30'" />
<xsl:with-param name="n" select="52" />
</xsl:call-template>
</output>
</xsl:template>
<xsl:template name="generate-weeks">
<xsl:param name="start-date"/>
<xsl:param name="n" select="52"/>
<xsl:if test="$n > 0">
<week start-date="{$start-date}"/>
<xsl:call-template name="generate-weeks">
<xsl:with-param name="start-date">
<xsl:variable name="JDN">
<xsl:call-template name="JDN">
<xsl:with-param name="date" select="$start-date" />
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="GD">
<xsl:with-param name="JDN" select="$JDN + 7" />
</xsl:call-template>
</xsl:with-param>
<xsl:with-param name="n" select="$n - 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="JDN">
<xsl:param name="date"/>
<xsl:variable name="year" select="substring($date, 1, 4)"/>
<xsl:variable name="month" select="substring($date, 6, 2)"/>
<xsl:variable name="day" select="substring($date, 9, 2)"/>
<xsl:variable name="a" select="floor((14 - $month) div 12)"/>
<xsl:variable name="y" select="$year + 4800 - $a"/>
<xsl:variable name="m" select="$month + 12*$a - 3"/>
<xsl:value-of select="$day + floor((153*$m + 2) div 5) + 365*$y + floor($y div 4) - floor($y div 100) + floor($y div 400) - 32045" />
</xsl:template>
<xsl:template name="GD">
<xsl:param name="JDN"/>
<xsl:variable name="f" select="$JDN + 1401 + floor((floor((4 * $JDN + 274277) div 146097) * 3) div 4) - 38"/>
<xsl:variable name="e" select="4*$f + 3"/>
<xsl:variable name="g" select="floor(($e mod 1461) div 4)"/>
<xsl:variable name="h" select="5*$g + 2"/>
<xsl:variable name="D" select="floor(($h mod 153) div 5 ) + 1"/>
<xsl:variable name="M" select="(floor($h div 153) + 2) mod 12 + 1"/>
<xsl:variable name="Y" select="floor($e div 1461) - 4716 + floor((14 - $M) div 12)"/>
<xsl:value-of select="$Y" />
<xsl:value-of select="format-number($M, '-00')"/>
<xsl:value-of select="format-number($D, '-00')"/>
</xsl:template>
</xsl:stylesheet>
这将产生:
结果
<?xml version="1.0" encoding="utf-8"?>
<output>
<week start-date="2020-11-30"/>
<week start-date="2020-12-07"/>
<week start-date="2020-12-14"/>
<week start-date="2020-12-21"/>
<week start-date="2020-12-28"/>
<week start-date="2021-01-04"/>
<week start-date="2021-01-11"/>
<week start-date="2021-01-18"/>
<week start-date="2021-01-25"/>
<week start-date="2021-02-01"/>
<week start-date="2021-02-08"/>
<week start-date="2021-02-15"/>
<week start-date="2021-02-22"/>
<week start-date="2021-03-01"/>
<week start-date="2021-03-08"/>
<week start-date="2021-03-15"/>
<week start-date="2021-03-22"/>
<week start-date="2021-03-29"/>
<week start-date="2021-04-05"/>
<week start-date="2021-04-12"/>
<week start-date="2021-04-19"/>
<week start-date="2021-04-26"/>
<week start-date="2021-05-03"/>
<week start-date="2021-05-10"/>
<week start-date="2021-05-17"/>
<week start-date="2021-05-24"/>
<week start-date="2021-05-31"/>
<week start-date="2021-06-07"/>
<week start-date="2021-06-14"/>
<week start-date="2021-06-21"/>
<week start-date="2021-06-28"/>
<week start-date="2021-07-05"/>
<week start-date="2021-07-12"/>
<week start-date="2021-07-19"/>
<week start-date="2021-07-26"/>
<week start-date="2021-08-02"/>
<week start-date="2021-08-09"/>
<week start-date="2021-08-16"/>
<week start-date="2021-08-23"/>
<week start-date="2021-08-30"/>
<week start-date="2021-09-06"/>
<week start-date="2021-09-13"/>
<week start-date="2021-09-20"/>
<week start-date="2021-09-27"/>
<week start-date="2021-10-04"/>
<week start-date="2021-10-11"/>
<week start-date="2021-10-18"/>
<week start-date="2021-10-25"/>
<week start-date="2021-11-01"/>
<week start-date="2021-11-08"/>
<week start-date="2021-11-15"/>
<week start-date="2021-11-22"/>
</output>
下一步是预处理输入记录,并为每个记录分配一周开始日的值。然后可以通过匹配两个开始日期将每个记录分配给相应的周。我建议你问一个单独的问题(或问题)。