我想在XSLT 2.0中編寫一個尾遞歸函數,該函數遍歷一個多值變量的日期並返回最早的一個。出於某種原因,我的功能不受SaxonHE9.4認定爲尾遞歸,我得到以下錯誤,當輸入文件已經超過150-200項左右:在tail_rec_test線73XSLT 2.0中的尾遞歸函數不起作用
錯誤。 xsl:調用太多嵌套函數 。可能是由於無限遞歸。在內置模板規則
這裏是我的XML輸入:
<?xml version="1.0"?>
<Events>
<Event>
<Date>2004-01-01</Date>
</Event>
<Event>
<Date>2003-01-01</Date>
</Event>
<Event>
<Date>2002-01-01</Date>
</Event>
<Event>
<Date>2001-01-01</Date>
</Event>
<Event>
<Date>2005-01-01</Date>
</Event>
<Event>
<Date>2006-01-01</Date>
</Event>
<Event>
<Date>2007-01-01</Date>
</Event>
<Event>
<Date>2008-01-01</Date>
</Event>
</Events>
這是我的XSL文件看起來像:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:own="http://ownfunctions">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:function name="own:findEarliestDate">
<xsl:param name="dates" as="xs:date*"/>
<xsl:variable name="size"><xsl:value-of select="count($dates)" /></xsl:variable>
<xsl:choose>
<xsl:when test="$size > 0">
<xsl:value-of select="own:findEarliestDate-helper($dates, $size, xs:date('2050-01-01'))" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="''"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
<xsl:function name="own:findEarliestDate-helper" as="xs:date">
<xsl:param name="items" as="xs:date*"/>
<xsl:param name="i" as="xs:integer"/>
<xsl:param name="curMin" as="xs:date"/>
<xsl:choose>
<xsl:when
test="$i = 0">
<xsl:value-of select="xs:date($curMin)"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="item" as="xs:date">
<xsl:value-of select="xs:date($items[$i])"/>
</xsl:variable>
<xsl:variable name="next" as="xs:date">
<xsl:choose>
<xsl:when test="$item < $curMin">
<xsl:value-of select="$item"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$curMin"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="own:findEarliestDate-helper($items, $i - 1, $next)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
<xsl:template match="Events">
<xsl:variable name="items" as="xs:date*">
<xsl:for-each select="Event">
<xsl:value-of select="xs:date(Date)"/>
</xsl:for-each>
</xsl:variable>
<Test>
<EarliestDate>
<xsl:value-of select="own:findEarliestDate($items)"/>
</EarliestDate>
</Test>
</xsl:template>
</xsl:stylesheet>
我怎樣才能變換它變成了一個正確的尾遞歸函數? 我已經測試了這個例子,但我不能將其應用到自己的代碼: http://www.nesterovsky-bros.com/weblog/2008/02/20/EfficientXslt20RecursionInSaxon9.aspx
感謝您的回覆速度快(+1)!我測試了短版本,它絕對有效(5000個事件很有效)。雖然很高興知道爲什麼我的函數不像尾遞歸函數那樣工作。它在150-200個事件中搜索,但這可能取決於VM堆大小。你可以請嘗試很多事件嗎?我可以更新輸入,但它會很大。只要說你喜歡什麼。再次感謝。 – Ivo
@Ivo,我發現你的問題,並用問題,解釋和簡單的解決方案更新了我的答案。 –
太棒了!它現在完美運行,謝謝! – Ivo