|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<xsl:stylesheet xmlns:dow="urn:dow-functions"
|
|
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
|
|
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
|
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
|
version="2.0">
|
|
|
|
<xsl:function name="dow:day-of-week" as="xs:integer">
|
|
<xsl:param name="date" as="xs:string"/>
|
|
<xsl:sequence select="xs:integer(format-date(xs:date($date), '[F1]', (), 'ISO', ()))"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="dow:day-to-string" as="xs:string">
|
|
<xsl:param name="R" as="xs:integer*"/>
|
|
<xsl:param name="F" as="xs:integer*"/>
|
|
<xsl:param name="N" as="xs:integer*"/>
|
|
<xsl:value-of>
|
|
<xsl:if test="exists($R)">
|
|
<xsl:sequence select="'R', $R"/>
|
|
</xsl:if>
|
|
<xsl:if test="exists($F)">
|
|
<xsl:sequence select="'F', $F"/>
|
|
</xsl:if>
|
|
<xsl:if test="exists($N)">
|
|
<xsl:sequence select="'N', $N"/>
|
|
</xsl:if>
|
|
</xsl:value-of>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="dow:merge-valday" as="map(*)*">
|
|
<xsl:param name="valday" as="map(*)*"/>
|
|
<xsl:param name="feastday" as="xs:string*"/>
|
|
<xsl:iterate select="$valday">
|
|
<xsl:param name="previous-valday" select="()" as="map(*)?"/>
|
|
<xsl:variable name="index" select="position()"/>
|
|
<xsl:variable name="current-valday" select="($previous-valday, .)[1]"/>
|
|
<xsl:variable name="next-valday" select="$valday[$index + 1]"/>
|
|
<xsl:variable name="merged-R" select="sort(distinct-values(($current-valday?R, $next-valday?R)))"/>
|
|
<xsl:variable name="merged-F" select="sort(distinct-values(($current-valday?F, $next-valday?F)))"/>
|
|
<xsl:variable name="hole-validFromDate" select="dow:next-day($current-valday?validToDate)"/>
|
|
<xsl:variable name="hole-validToDate" select="dow:previous-day($next-valday?validFromDate)"/>
|
|
<xsl:variable name="hole-val" select="map{'validFromDate': $hole-validFromDate, 'validToDate': $hole-validToDate}"/>
|
|
<xsl:variable name="hole-valday" select="dow:val-to-continuous-valday($hole-val, $feastday)[exists($next-valday)]"/>
|
|
<xsl:variable name="merged-N" select="sort(distinct-values(($current-valday?N, $next-valday?N, $hole-valday?R)))"/>
|
|
<xsl:variable name="add-now" select="empty($next-valday) or exists(($merged-R[. = ($merged-F, $hole-valday?R)], $merged-F[. = $hole-valday?R], $merged-N[. = ($merged-R, $merged-F)]))"/>
|
|
<xsl:if test="$add-now">
|
|
<xsl:sequence select="$current-valday"/>
|
|
</xsl:if>
|
|
<xsl:variable name="merged-valday" as="map(*)?">
|
|
<xsl:if test="not($add-now)">
|
|
<xsl:map>
|
|
<xsl:map-entry key="'validFromDate'" select="$current-valday?validFromDate"/>
|
|
<xsl:map-entry key="'validToDate'" select="$next-valday?validToDate"/>
|
|
<xsl:map-entry key="'R'" select="$merged-R"/>
|
|
<xsl:map-entry key="'F'" select="$merged-F"/>
|
|
<xsl:map-entry key="'N'" select="$merged-N"/>
|
|
</xsl:map>
|
|
</xsl:if>
|
|
</xsl:variable>
|
|
<xsl:next-iteration>
|
|
<xsl:with-param name="previous-valday" select="$merged-valday"/>
|
|
</xsl:next-iteration>
|
|
</xsl:iterate>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="dow:next-day" as="xs:string">
|
|
<xsl:param name="date" as="xs:string"/>
|
|
<xsl:sequence select="dow:shift-day($date, 1)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="dow:previous-day" as="xs:string">
|
|
<xsl:param name="date" as="xs:string"/>
|
|
<xsl:sequence select="dow:shift-day($date, -1)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="dow:shift-day" as="xs:string">
|
|
<xsl:param name="date" as="xs:string"/>
|
|
<xsl:param name="nbOfDays" as="xs:integer"/>
|
|
<xsl:choose>
|
|
<xsl:when test="$nbOfDays gt 0">
|
|
<!-- Add abs to avoid compilation warning -->
|
|
<xsl:value-of select="xs:date($date) + xs:dayTimeDuration(concat('P', abs($nbOfDays), 'D'))"/>
|
|
</xsl:when>
|
|
<xsl:when test="$nbOfDays lt 0">
|
|
<xsl:value-of select="xs:date($date) - xs:dayTimeDuration(concat('P', abs($nbOfDays), 'D'))"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$date"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="dow:val-to-continuous-valday" as="map(*)*">
|
|
<xsl:param name="val" as="map(*)*"/>
|
|
<xsl:param name="feastday" as="xs:string*"/>
|
|
<xsl:for-each select="$val">
|
|
<xsl:variable name="date" select="dow:val-to-date(.)"/>
|
|
<xsl:variable name="day" select="for $d in $date return if ($d = $feastday) then 7 else dow:day-of-week($d)"/>
|
|
<xsl:variable name="R" select="sort(distinct-values($day))"/>
|
|
<xsl:sequence select="map:merge((map:entry('R', $R), .))"/>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="dow:val-to-date" as="xs:string*">
|
|
<xsl:param name="val" as="map(*)*"/>
|
|
<xsl:for-each select="$val">
|
|
<xsl:variable name="validFromDate" select="?validFromDate"/>
|
|
<xsl:variable name="validToDate" select="?validToDate"/>
|
|
<xsl:variable name="nb-of-days" select="xs:integer((xs:date($validToDate) - xs:date($validFromDate)) div xs:dayTimeDuration('P1D'))"/>
|
|
<xsl:for-each select="0 to $nb-of-days">
|
|
<xsl:sequence select="dow:shift-day($validFromDate, .)"/>
|
|
</xsl:for-each>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="dow:val-to-valday" as="map(*)*">
|
|
<xsl:param name="val" as="map(*)*"/>
|
|
<xsl:param name="feastday" as="xs:string*"/>
|
|
<xsl:variable name="continuous-valday" select="dow:val-to-continuous-valday($val, $feastday)"/>
|
|
<xsl:sequence select="dow:merge-valday($continuous-valday, $feastday)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="dow:valday-to-string" as="xs:string*">
|
|
<xsl:param name="valday" as="map(*)*"/>
|
|
<xsl:for-each select="$valday">
|
|
<xsl:sequence select="concat('val=[', ?validFromDate, ',', ?validToDate, '] day=', dow:day-to-string(?R, ?F, ?N))"/>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
</xsl:stylesheet>
|