获取基于 Day XSLT 2.0/XSLT 3.0 的日期和地图值列表

Get list of Dates and map values based on Day XSLT2.0/XSLT3.0

我有这样的场景:

需要列出开始日期和结束日期之间的日期,并根据类型 'Weekly' 或 'Bi-Weekly' 需要将日期节点(星期一、星期二...)映射到相应的日期。

Week1 是 StartDate 的那一周,Week2 是 StartDate 的第二周(Week1 之后的那一周)

如果类型是每周: 需要将 Day 节点值从 Week1 节点映射到该周的相应日期并不断重复直到 EndDate

如果类型是双周: 需要在前两周映射 Week1 节点和 Week2 节点的节点值,并不断重复直到结束日期

StartDate 可以是一周中的任何一天,不一定是一周的开始(星期一)。

下面是我的XML:

<Data>
    <Root>
        <Type>Bi-Weekly</Type>
        <StartDate>2022-02-22</StartDate>
        <EndDate>2022-12-31</EndDate>
        <Week1>
            <Monday>4</Monday>
            <Tuesday>0</Tuesday>
            <Wednesday>4</Wednesday>
            <Thursday>0</Thursday>
            <Friday>4</Friday>
        </Week1>
        <Week2>
            <Monday>0</Monday>
            <Tuesday>4</Tuesday>
            <Wednesday>0</Wednesday>
            <Thursday>4</Thursday>
            <Friday>0</Friday>
        </Week2>
    </Root>
    <Root>
        <Type>Weekly</Type>
        <StartDate>2023-02-12</StartDate>
        <EndDate>2023-12-15</EndDate>
        <Week1>
            <Monday>4</Monday>
            <Tuesday>0</Tuesday>
            <Wednesday>4</Wednesday>
            <Thursday>0</Thursday>
            <Friday>4</Friday>
        </Week1>
        <Week2>
            <Monday>0</Monday>
            <Tuesday>4</Tuesday>
            <Wednesday>0</Wednesday>
            <Thursday>4</Thursday>
            <Friday>0</Friday>
        </Week2>
    </Root>
</Data>

我想要的双周输出是:

22-Feb-22|Tuesday|0
23-Feb-22|Wednesday|4
24-Feb-22|Thursday|0
25-Feb-22|Friday|4
28-Feb-22|Monday|0
1-Mar-22|Tuesday|4
2-Mar-22|Wednesday|0
3-Mar-22|Thursday|4
4-Mar-22|Friday|0
.
.
.
20-Dec-22|Tuesday|4
21-Dec-22|Wednesday|0
22-Dec-22|Thursday|4
23-Dec-22|Friday|0
26-Dec-22|Monday|4
27-Dec-22|Tuesday|0
28-Dec-22|Wednesday|4
29-Dec-22|Thursday|0
30-Dec-22|Friday|4

我想要的每周输出是:

22-Feb-22|Tuesday|0
23-Feb-22|Wednesday|4
24-Feb-22|Thursday|0
25-Feb-22|Friday|4
28-Feb-22|Monday|4
1-Mar-22|Tuesday|0
2-Mar-22|Wednesday|4
3-Mar-22|Thursday|0
4-Mar-22|Friday|4
7-Mar-22|Monday|4
8-Mar-22|Tuesday|0
.
.
.
19-Dec-22|Monday|4
20-Dec-22|Tuesday|0
21-Dec-22|Wednesday|4
22-Dec-22|Thursday|0
23-Dec-22|Friday|4
26-Dec-22|Monday|4
27-Dec-22|Tuesday|0
28-Dec-22|Wednesday|4
29-Dec-22|Thursday|0
30-Dec-22|Friday|4

另外。 .删除输出中值为“0”的日期会有所帮助。

输入文件的结构可以修改,如果这样可以简化过程,例如

<Data>
    <Root>
        <Type>Bi-Weekly</Type>
        <StartDate>2022-02-21</StartDate>
        <EndDate>2022-12-31</EndDate>
        <Week>
            <W1Monday>4</W1Monday>
            <W1Tuesday>0</W1Tuesday>
            <W1Wednesday>4</W1Wednesday>
            <W1Thursday>0</W1Thursday>
            <W1Friday>4</W1Friday>
            <W2Monday>0</W2Monday>
            <W2Tuesday>4</W2Tuesday>
            <W2Wednesday>0</W2Wednesday>
            <W2Thursday>4</W2Thursday>
            <W2Friday>0</W2Friday>
        </Week>
    </Root>
</Data>

谢谢!

当前代码:https://xsltfiddle.liberty-development.net/nbspVb7/4

看看这是否有帮助:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:key name="week1" match="Week1/*" use="name()" />
<xsl:key name="week2" match="Week2/*" use="name()" />

<xsl:template match="Root">
    <xsl:variable name="root" select="." />
    <xsl:variable name="startDate" select="xs:date(StartDate)" />
    <xsl:variable name="n" select="(xs:date(EndDate) - $startDate) div xs:dayTimeDuration('P1D')" />
    <xsl:for-each select="0 to xs:integer($n)">
        <xsl:variable name="week2" select=". idiv 7 mod 2" />
        <xsl:variable name="date" select="$startDate + xs:dayTimeDuration('P1D') * ." />
        <xsl:variable name="day-of-week" select="format-date($date, '[F]')" />      
        <xsl:variable name="value" select="key(if ($week2) then 'week2' else 'week1', $day-of-week, $root)" />      
        <xsl:if test="$value > 0">
            <xsl:value-of select="format-date($date, '[D01]-[M01]-[Y0001]'), $day-of-week, $value" separator="|"/>
            <xsl:text>&#10;</xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

这需要调整以适应 <Type>Weekly</Type> - 但这应该不会太难。另外,如果我没记错的话,它假定 StartDate 总是星期一。


演示https://xsltfiddle.liberty-development.net/nbspVb7/5