如何从逗号分隔的列表中获取最大/最小日期

时间:2019-04-10 08:27:20

标签: xml xslt-2.0

我有一串用逗号(,)分隔的日期 看起来像“ 20180116,20180115,20180126”

我需要从该字符串中获取最小日期和最大日期。使用xslt 2.0

XSLT代码如下:

<xsl:variable name="allDates"><xsl:value-of select="20180116,20180115,20180126"/> </xsl:variable>


<xsl:function name="getLicencingWindowStart">
    <xsl:param name="dates" />
    <xsl:variable name="smallestDateSort" select="tokenize(normalize-space($dates),',')" />
    <xsl:for-each select="$smallestDateSort">
        <xsl:sort select="." order="descending"/>
        <xsl:if test="position() = last()">
            <xsl:value-of select="."/>
        </xsl:if>
        <xsl:if test="position() = 1">
            <xsl:value-of select="."/>
        </xsl:if>
    </xsl:for-each>
</xsl:function>

o / p:

预期结果是:

最小:“ 20180115”

最大:“ 20180126”

o / p:

<App_Data App="VOD" Name="smallestDate" Value=""/>
<App_Data App="VOD" Name="largestdate" Value="20180126"/>

2 个答案:

答案 0 :(得分:0)

假设输入为

<?xml version="1.0" encoding="UTF-8"?>
<root>20190101,20190201,2019051,20190401</root>

获得所需输出的一种方法是:

<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 omit-xml-declaration="yes" indent="yes" />

<xsl:template match="/">
    <xsl:variable name="date" select="tokenize(normalize-space(/root),',')" />

    <xsl:for-each select="$date">
        <xsl:sort select="." order="descending" />
        <xsl:if test="position() = last()">
            Smallest: <xsl:value-of select="." />
        </xsl:if>
        <xsl:if test="position() = 1">
            Largest: <xsl:value-of select="." />
        </xsl:if>
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

编辑:

根据您的评论,如果要使用 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 omit-xml-declaration="yes" indent="yes" />

<xsl:template match="/">
    <xsl:variable name="date" select="tokenize(normalize-space(/root),',')" />

    Largest: <xsl:sequence select="max($date)"/>
    Smallest: <xsl:sequence select="min($date)"/>

</xsl:template>
</xsl:stylesheet>

答案 1 :(得分:0)

对于想在 XSLT 1.0 中进行操作的任何人,请构建如下模板:

<!-- template: (recursive) find the smallest or largest value in a list of comma-separated values -->
<xsl:template name="findincsv">
    <xsl:param name="csv"/>
    <xsl:param name="which" select="'largest'"/> <!-- smallest or largest (default) -->

    <!-- first value in csv -->
    <xsl:variable name="first" select="substring-before($csv,',')"/> 

    <xsl:choose>
        <!-- if this is the only value: return this one  -->    
        <xsl:when test="not(contains($csv,','))">
            <xsl:value-of select="$csv"/>
        </xsl:when>

        <!-- if this is not the only value: compare the first with the result of this template entering the rest -->
        <xsl:otherwise>
            <!-- find the wanted value of everything after the first -->
            <xsl:variable name="findinrest">
                <xsl:call-template name="findincsv">
                    <xsl:with-param name="csv" select="substring-after($csv,',')" />
                    <xsl:with-param name="which" select="$which"/>
                </xsl:call-template>
            </xsl:variable>

            <!-- compare to the first -->
            <xsl:choose>
                <xsl:when test="($which = 'largest' and $first &gt; $findinrest)
                                or ($which = 'smallest' and $first &lt; $findinrest)">
                    <xsl:value-of select="$first"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$findinrest"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:otherwise>
    </xsl:choose>

</xsl:template>

然后按如下所示调用模板:

<xsl:call-template name="findincsv">
    <xsl:with-param name="csv" select="$csv" />
    <xsl:with-param name="which" select="'largest'"/>
</xsl:call-template>

注意:该模板仅适用于“纯净” CSV,开头或结尾没有“松散”逗号。 示例如何删除结束逗号:

<xsl:with-param name="csv" select="substring($csv,1,(string-length($csv) - 1))" />