我需要獲取兩個日期之間的日期列表 - 例如,我有開始日期03302012和結束日期05302012,我需要一個像XSLT 1.0:使用XSLT獲取兩個日期之間的日期列表
03302012 03312012 04012012 04022012 ... 05282012 05292012 05302012
- 輸出隨意使用你的日期格式 - 我會自己做轉型。 非常感謝!
我需要獲取兩個日期之間的日期列表 - 例如,我有開始日期03302012和結束日期05302012,我需要一個像XSLT 1.0:使用XSLT獲取兩個日期之間的日期列表
03302012 03312012 04012012 04022012 ... 05282012 05292012 05302012
您可以通過使用遞歸模板來做到這一點。這不是最好的解決方案,因爲這會受到堆棧溢出或內存不足錯誤的影響(如果您給它的日期間隔足夠大),但它可能是一個開始的地方。
下面的例子需要的第一件事是檢查生成的值並確保它是有效的日期(您可以在網上找到一些示例;我只是使用a sample from an open source project並在該示例中僅導入了該文件保持較短)。
然後,我們的想法是通過將一天添加到前一天,然後將一天添加到當前日期來生成日期。如果這一天溢出,您將在月份中添加一個,並從第1天開始重新開始。如果月份溢出,您將與年份相同,並從第1個月開始。理論上,唯一永不會溢出的是年份(但您會限制與間隔的最終值)。
您生成日期並驗證它。如果它是有效的並且尚未達到間隔的結束時間,則嘗試通過向其添加日期來生成另一個日期(這就是塊X中發生的情況)。
當你得到一個無效的值,然後溢出。它只能是一天或一個月(如上所述)。我首先檢查月份(方塊Y)。如果是這樣,我從第一個月的第一天開始,但是第二年開始。如果是溢出的那一天(塊Z),那麼我從下個月的第一天開始。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="http://www.getsymphony.com/download/xslt-utilities/source-code/54294/"/>
<xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:variable name="startDate" select="'03302012'" /> <!-- MMddyyyy format -->
<xsl:variable name="endDate" select="'05302012'" /> <!-- MMddyyyy format -->
<xsl:template match="/">
<values>
<xsl:call-template name="GenerateList">
<xsl:with-param name="day" select="number(substring($startDate, 3, 2))" />
<xsl:with-param name="month" select="number(substring($startDate, 1, 2))" />
<xsl:with-param name="year" select="number(substring($startDate, 5))" />
</xsl:call-template>
</values>
</xsl:template>
<xsl:template name="GenerateList">
<xsl:param name="day" select="1" />
<xsl:param name="month" select="1" />
<xsl:param name="year" select="1" />
<!-- 1 = valid, 0 = invalid according to the imported file -->
<xsl:variable name="validationResult">
<xsl:call-template name="date-is-valid">
<xsl:with-param name="day" select="$day"/>
<xsl:with-param name="month" select="$month"/>
<xsl:with-param name="year" select="$year"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$validationResult = 0">
<xsl:choose>
<xsl:when test="$month > 12">
<!-- block Y -->
<xsl:call-template name="GenerateList">
<xsl:with-param name="day" select="1" />
<xsl:with-param name="month" select="1" />
<xsl:with-param name="year" select="$year + 1" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- block Z -->
<xsl:call-template name="GenerateList">
<xsl:with-param name="day" select="1" />
<xsl:with-param name="month" select="$month + 1" />
<xsl:with-param name="year" select="$year" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<!-- block X -->
<!-- same MMddyyyy format as the interval values -->
<xsl:variable name="currentDate" select="concat(format-number($month, '00'), format-number($day, '00'), $year)" />
<value>
<xsl:value-of select="$currentDate" />
</value>
<xsl:if test="not($currentDate = $endDate)">
<xsl:call-template name="GenerateList">
<xsl:with-param name="day" select="$day + 1" />
<xsl:with-param name="month" select="$month" />
<xsl:with-param name="year" select="$year" />
</xsl:call-template>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
謝謝你,波格丹!這很酷,適合我! – 2012-04-27 09:11:45
不幸的是,XSLT 1.0本身並不適合這樣的任務,但其環境通常是這樣的。下面是一些方法我用自己:
最簡單的解決方案通常是做出這樣的列表中的輸入的一部分=)
XSLT轉換通常是與特定一個較大的應用程序的一部分XSLT處理器,它允許使用特定手段來擴展。你可以編寫一個擴展函數(使用Java,Javascript,PHP,Python取決於處理器),它返回所需的節點集。另一個但類似的選擇是註冊一個「流」(至少PHP),並使用document
函數獲取節點集,其中url爲app://Dates/listdates?start=a&end=b
。缺點是樣式表與應用程序耦合,無法單獨開發。
大多數XSTL處理器都支持EXSLT擴展。您可以使用日期擴展來計算日期之間的天數,使用字符串擴展中的padding
函數生成一個字符串長度,將字符串拆分爲空字符串以獲取(需要的長度的)標記列表並迭代列表使用node-set
函數並使用date-add
將當前節點位置添加到第一個日期。
按照Bogdan的建議,使用純XSLT和遞歸模板。
嗨,別忘了接受答案。 – 2012-05-17 05:35:22