使用 XSLT 检查两个日期之间的差异
Check difference between two dates using XSLT
1]我有以下输入 xml1:
<TimeLimit Start="2022-02-24" End="2022-03-04"/>
<Tasks>
<TaskRate RateCode="Test">
<Rates>
<Rate BeginDate="2022-02-24" EndDate="2022-02-25" >
<Base Amount="100.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-02-26" EndDate="2022-03-01" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-03-02" EndDate="2022-03-03" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
</Rates>
</TaskRate>
</Tasks>
我想要如下输出:
<TimeLimit Start="2022-02-24" End="2022-03-04"/>
<Tasks>
<TaskRate RateCode="Test">
<Rates>
<Rate BeginDate="2022-02-24" EndDate="2022-02-25" >
<Base Amount="100.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-02-25" EndDate="2022-03-02" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-03-02" EndDate="2022-03-04" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
</Rates>
</TaskRate>
</Tasks>
2]当我输入以下内容时 xml2:
<TimeLimit Start="2022-02-24" End="2022-03-04"/>
<Tasks>
<TaskRate RateCode="Test">
<Rates>
<Rate BeginDate="2022-02-24" EndDate="2022-02-26" >
<Base Amount="100.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-02-26" EndDate="2022-03-02" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-03-02" EndDate="2022-03-04" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
</Rates>
</TaskRate>
</Tasks>
然后我想要输出如下:
<TimeLimit Start="2022-02-24" End="2022-03-04"/>
<Tasks>
<TaskRate RateCode="Test">
<Rates>
<Rate BeginDate="2022-02-24" EndDate="2022-02-26" >
<Base Amount="100.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-02-26" EndDate="2022-03-02" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-03-02" EndDate="2022-03-04" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
</Rates>
</TaskRate>
</Tasks>
这意味着对于连续或非连续日期范围作为输入,我总是希望输出 xml 具有连续日期范围。
我正在使用以下 XSLT 代码,但它不起作用:
<Rates>
<xsl:for-each select="Rates/Rate">
<Rate>
<xsl:if test="@BeginDate and not(@BeginDate='')">
<xsl:attribute name="BeginDate">
<xsl:value-of select="@BeginDate" />
</xsl:attribute>
</xsl:if>
<xsl:choose>
<xsl:when test="(xs:date(following-sibling::Rate[1]/@BeginDate) - xs:date(@EndDate)) = 1">
<xsl:attribute name="EndDate">
<xsl:value-of select="xs:date(@EndDate)+xs:dayTimeDuration('P1D')" />
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:if test="@EndDate and not(@EndDate='')">
<xsl:attribute name="EndDate">
<xsl:value-of select="@EndDate" />
</xsl:attribute>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="xs:date(/TimeLimit/@End) - @EndDate = 1">
<xsl:attribute name="EndDate">
<xsl:value-of select="xs:date(@EndDate)+xs:dayTimeDuration('P1D')" />
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:if test="@EndDate and not(@EndDate='')">
<xsl:attribute name="EndDate">
<xsl:value-of select="@EndDate" />
</xsl:attribute>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</Rate>
</xsl:for-each>
</Rates>
有人可以帮忙吗?
在下面的 xslt 中我做了 2 个假设:
日期可以相差不止一天,并且还应遵守 TimeLimit/@start。那么就不需要 date-calculation 了。请告诉我这是否正确?
因为你的 xml 没有 root-element,这是 xml 我用过:
<TasksGroup>
<TimeLimit Start="2022-02-24" End="2022-03-04"/>
<Tasks>
<TaskRate RateCode="Test">
<Rates>
<Rate BeginDate="2022-02-24" EndDate="2022-02-25" >
<Base Amount="100.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-02-26" EndDate="2022-03-01" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-03-02" EndDate="2022-03-03" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
</Rates>
</TaskRate>
</Tasks>
</TasksGroup>
这是 xslt
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="#all">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="timeLimt" as="element()" select="/*/TimeLimit[1]"/>
<xsl:template match="Rate">
<xsl:copy>
<xsl:choose>
<xsl:when test="position()=1">
<xsl:attribute name="BeginDate">
<xsl:value-of select="$timeLimt/@Start" />
</xsl:attribute>
</xsl:when>
<xsl:when test="@BeginDate[not(.='')]">
<xsl:copy-of select="@BeginDate"/>
</xsl:when>
</xsl:choose>
<xsl:choose>
<xsl:when test="position()=last()">
<xsl:attribute name="EndDate">
<xsl:value-of select="$timeLimt/@End" />
</xsl:attribute>
</xsl:when>
<xsl:when test="following-sibling::*[1][@BeginDate[not(.='')]]">
<xsl:attribute name="EndDate">
<xsl:value-of select="following-sibling::*[1]/@BeginDate" />
</xsl:attribute>
</xsl:when>
<xsl:when test="@EndDate[not(.='')]">
<xsl:copy-of select="@EndDate"/>
</xsl:when>
</xsl:choose>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
结果:
<TasksGroup>
<TimeLimit Start="2022-02-24" End="2022-03-04"/>
<Tasks>
<TaskRate RateCode="Test">
<Rates>
<Rate BeginDate="2022-02-24" EndDate="2022-02-26">
<Base Amount="100.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-02-26" EndDate="2022-03-02">
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-03-02" EndDate="2022-03-04">
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
</Rates>
</TaskRate>
</Tasks>
</TasksGroup>
1]我有以下输入 xml1:
<TimeLimit Start="2022-02-24" End="2022-03-04"/>
<Tasks>
<TaskRate RateCode="Test">
<Rates>
<Rate BeginDate="2022-02-24" EndDate="2022-02-25" >
<Base Amount="100.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-02-26" EndDate="2022-03-01" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-03-02" EndDate="2022-03-03" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
</Rates>
</TaskRate>
</Tasks>
我想要如下输出:
<TimeLimit Start="2022-02-24" End="2022-03-04"/>
<Tasks>
<TaskRate RateCode="Test">
<Rates>
<Rate BeginDate="2022-02-24" EndDate="2022-02-25" >
<Base Amount="100.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-02-25" EndDate="2022-03-02" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-03-02" EndDate="2022-03-04" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
</Rates>
</TaskRate>
</Tasks>
2]当我输入以下内容时 xml2:
<TimeLimit Start="2022-02-24" End="2022-03-04"/>
<Tasks>
<TaskRate RateCode="Test">
<Rates>
<Rate BeginDate="2022-02-24" EndDate="2022-02-26" >
<Base Amount="100.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-02-26" EndDate="2022-03-02" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-03-02" EndDate="2022-03-04" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
</Rates>
</TaskRate>
</Tasks>
然后我想要输出如下:
<TimeLimit Start="2022-02-24" End="2022-03-04"/>
<Tasks>
<TaskRate RateCode="Test">
<Rates>
<Rate BeginDate="2022-02-24" EndDate="2022-02-26" >
<Base Amount="100.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-02-26" EndDate="2022-03-02" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-03-02" EndDate="2022-03-04" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
</Rates>
</TaskRate>
</Tasks>
这意味着对于连续或非连续日期范围作为输入,我总是希望输出 xml 具有连续日期范围。 我正在使用以下 XSLT 代码,但它不起作用:
<Rates>
<xsl:for-each select="Rates/Rate">
<Rate>
<xsl:if test="@BeginDate and not(@BeginDate='')">
<xsl:attribute name="BeginDate">
<xsl:value-of select="@BeginDate" />
</xsl:attribute>
</xsl:if>
<xsl:choose>
<xsl:when test="(xs:date(following-sibling::Rate[1]/@BeginDate) - xs:date(@EndDate)) = 1">
<xsl:attribute name="EndDate">
<xsl:value-of select="xs:date(@EndDate)+xs:dayTimeDuration('P1D')" />
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:if test="@EndDate and not(@EndDate='')">
<xsl:attribute name="EndDate">
<xsl:value-of select="@EndDate" />
</xsl:attribute>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="xs:date(/TimeLimit/@End) - @EndDate = 1">
<xsl:attribute name="EndDate">
<xsl:value-of select="xs:date(@EndDate)+xs:dayTimeDuration('P1D')" />
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:if test="@EndDate and not(@EndDate='')">
<xsl:attribute name="EndDate">
<xsl:value-of select="@EndDate" />
</xsl:attribute>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</Rate>
</xsl:for-each>
</Rates>
有人可以帮忙吗?
在下面的 xslt 中我做了 2 个假设:
日期可以相差不止一天,并且还应遵守 TimeLimit/@start。那么就不需要 date-calculation 了。请告诉我这是否正确?
因为你的 xml 没有 root-element,这是 xml 我用过:
<TasksGroup>
<TimeLimit Start="2022-02-24" End="2022-03-04"/>
<Tasks>
<TaskRate RateCode="Test">
<Rates>
<Rate BeginDate="2022-02-24" EndDate="2022-02-25" >
<Base Amount="100.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-02-26" EndDate="2022-03-01" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-03-02" EndDate="2022-03-03" >
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
</Rates>
</TaskRate>
</Tasks>
</TasksGroup>
这是 xslt
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="#all">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="timeLimt" as="element()" select="/*/TimeLimit[1]"/>
<xsl:template match="Rate">
<xsl:copy>
<xsl:choose>
<xsl:when test="position()=1">
<xsl:attribute name="BeginDate">
<xsl:value-of select="$timeLimt/@Start" />
</xsl:attribute>
</xsl:when>
<xsl:when test="@BeginDate[not(.='')]">
<xsl:copy-of select="@BeginDate"/>
</xsl:when>
</xsl:choose>
<xsl:choose>
<xsl:when test="position()=last()">
<xsl:attribute name="EndDate">
<xsl:value-of select="$timeLimt/@End" />
</xsl:attribute>
</xsl:when>
<xsl:when test="following-sibling::*[1][@BeginDate[not(.='')]]">
<xsl:attribute name="EndDate">
<xsl:value-of select="following-sibling::*[1]/@BeginDate" />
</xsl:attribute>
</xsl:when>
<xsl:when test="@EndDate[not(.='')]">
<xsl:copy-of select="@EndDate"/>
</xsl:when>
</xsl:choose>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
结果:
<TasksGroup>
<TimeLimit Start="2022-02-24" End="2022-03-04"/>
<Tasks>
<TaskRate RateCode="Test">
<Rates>
<Rate BeginDate="2022-02-24" EndDate="2022-02-26">
<Base Amount="100.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-02-26" EndDate="2022-03-02">
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
<Rate BeginDate="2022-03-02" EndDate="2022-03-04">
<Base Amount="200.00" CurrencyCode="EUR"/>
</Rate>
</Rates>
</TaskRate>
</Tasks>
</TasksGroup>