在比较XSLT代码中的日期时遇到无效的日期问题

问题描述

我有一个要求,其中我必须验证以下两种情况:要约开始日期应早于要约结束日期,而要约开始日期帐户应在帐户开始日期之后。如果未满足任何一种情况,则应该引发错误

要约开始日期和要约结束日期的值将分别以空格分隔的格式显示在xml标签和xml标签中。

下面是示例xml代码

<Accounts>
    <Account>
        <AccountStartDate>2020-12-01<AccountStartDate>
        <offerStartDate>2020-10-02 2020-11-02</offerStartDate>
        <offerEndDate>2019-10-02 2019-11-02</offerEndDate>
    </Account>
</Accounts>

下面是示例xslt代码

<xsl:for-each select="Accounts/Account">
    <xsl:variable name="offerSDate" select="offerStartDate"/>
    <xsl:variable name="offerEDate" select="offerEndDate"/>
                
    <xsl:if test="$offerSDate &gt; xs:date(AccountStartDate)">
        <Error>
            <xsl:text>Error: Invalid offer Date &#xA;</xsl:text>
        </Error>
    </xsl:if>
    <xsl:if test="$offerSDate &gt; $offerEDate">
        <Error>
            <xsl:text>Error: Invalid offer Date &#xA;</xsl:text>
        </Error>
    </xsl:if>
</xsl:for-each>

执行xslt代码后,我收到了无效日期“ 2020-10-02 2020-11-02”的问题。

解决方法

如果要对offerStartDate中的每个日期进行单独比较,则可以(在XSLT 2.0中)执行以下任一操作:

    <xsl:for-each select="Account">
        <xsl:if test="some $offerStartDate in tokenize(offerStartDate,' ') satisfies xs:date($offerStartDate) gt xs:date(AccountStartDate)">
            <Error>error message</Error>
        </xsl:if>
    </xsl:for-each>

或(取决于测试的含义)

    <xsl:for-each select="Account">
        <xsl:if test="every $offerStartDate in tokenize(offerStartDate,' ') satisfies xs:date($offerStartDate) gt xs:date(AccountStartDate)">
            <Error>error message</Error>
        </xsl:if>
    </xsl:for-each>
,

仅使用XSLT的最简单方法就是将XML转换自:

<Accounts>
    <Account>
        <AccountStartDate>2020-12-01</AccountStartDate>
        <offerStartDate>2020-10-02 2020-11-02</offerStartDate>
        <offerEndDate>2019-10-02 2019-11-02</offerEndDate>
    </Account>
</Accounts>

类似:

<Accounts>
    <Account>
        <AccountStartDate>2020-12-01</AccountStartDate>
        <offer>
         <offerStartDate>2020-10-02</offerStartDate>
         <offerEndDate>2019-10-02</offerEndDate>
        </offer>
        <offer>
         <offerStartDate>2020-11-02</offerStartDate>
         <offerEndDate>2019-11-02</offerEndDate>
        </offer>
    </Account>
</Accounts>