我被困在遞歸中,想知道是否有人能幫助我。XSLT 1.0遞歸
我有<Receipts>
和<Deposits>
元件中,不是冗長,即,一個元件<Receipts>
不具有屬性,以顯示它是什麼<Deposit>
朝向。我需要計算出<Deposits>
「還款到期」,並且最後一張收據是否已付款(如果有的話)。
我想用下面的代碼來做到這一點:
的想法就是把第一個存款,看看是否有收據。如果存款沒有全額支付並且有更多的收據 - 將所有相同的參數稱爲recorsive功能,除了現在計入以下收據。
如果沒有更多的收據或存款支付 - 正確處理(添加必需的屬性)。否則,繼續第二次存款。等等。
然而,隨着錯誤消息的XSLT崩潰,「一個處理器堆棧溢出 - 可能的原因是無窮的遞歸模板」
我真的很感激任何幫助/ TEPS ......我不是遞歸這個偉大並不明白爲什麼我的這裏不起作用。
謝謝! :)
<!-- Accumulate all the deposits with @DueAmount attribute -->
<xsl:variable name="depositsClassified">
<xsl:call-template name="classifyDeposits">
<!-- a node-list of all Deposits elements ordered by DueDate Acs -->
<xsl:with-param name="depositsAll" select="$deposits"/>
<xsl:with-param name="depositPrevAmount" select="'0'"/>
<!-- a node-list of all Receipts elements ordered by ReceivedDate Acs -->
<xsl:with-param name="receiptsAll" select="$receiptsAsc"/>
<xsl:with-param name="receiptCount" select="'1'"/>
</xsl:call-template>
</xsl:variable>
<xsl:template name="classifyDeposits">
<xsl:param name="depositsAll"/>
<xsl:param name="depositPrevAmount" select="'0'"/>
<xsl:param name="receiptsAll"/>
<xsl:param name="receiptCount"/>
<xsl:if test="$depositsAll">
<!-- Do required operations for the 1st deposit -->
<xsl:variable name="depositFirst" select="$depositsAll[1]"/>
<xsl:variable name="receiptSum">
<xsl:choose>
<xsl:when test="$receiptsAll">
<xsl:value-of select="sum($receiptsAll[position() <= $receiptCount]/@ActionAmount)"/>
</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="diff" select="$depositPrevAmount + $depositFirst/@DepositTotalAmount - $receiptSum"/>
<xsl:choose>
<xsl:when test="$diff > 0 and
$receiptCount < $receiptsQuantityOf">
<xsl:call-template name="classifyDeposits">
<xsl:with-param name="depositsAll" select="$depositsAll"/>
<xsl:with-param name="depositPrevAmount" select="$depositPrevAmount"/>
<xsl:with-param name="receiptsAll" select="$receiptsAll"/>
<xsl:with-param name="receiptCount" select="$receiptCount + 1"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- Record changes to the deposit (@DueAmount and receipt ReceivedDate) -->
<xsl:apply-templates select="$depositFirst" mode="defineDeposit">
<xsl:with-param name="diff" select="$diff"/>
<xsl:with-param name="latestReceiptForDeposit" select="$receiptsAll[position() = $receiptCount]"/>
</xsl:apply-templates>
<!-- Recursive call to the next deposit -->
<xsl:call-template name="classifyDeposits">
<xsl:with-param name="depositsAll" select="$depositsAll[position() > 1]"/>
<xsl:with-param name="depositPrevAmount" select="$depositPrevAmount + $depositFirst/@DepositTotalAmount"/>
<xsl:with-param name="receiptsAll" select="$receiptsAll"/>
<xsl:with-param name="receiptCount" select="'1'"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<!-- Determine deposit's status, due amount and payment received date if any -->
<xsl:template match="Deposits" mode="defineDeposit">
<xsl:param name="diff"/>
<xsl:param name="latestReceiptForDeposit"/>
<xsl:choose>
<xsl:when test="$diff <= 0">
<xsl:apply-templates select="." mode="addAttrs">
<xsl:with-param name="status" select="'paid'"/>
<xsl:with-param name="dueAmount" select="'0'"/>
<xsl:with-param name="receipt" select="$latestReceiptForDeposit"/>
</xsl:apply-templates>
</xsl:when>
<xsl:when test="$diff = ./@DepositTotalAmount">
<xsl:apply-templates select="." mode="addAttrs">
<xsl:with-param name="status" select="'due'"/>
<xsl:with-param name="dueAmount" select="$diff"/>
</xsl:apply-templates>
</xsl:when>
<xsl:when test="$diff < ./@DepositTotalAmount">
<xsl:apply-templates select="." mode="addAttrs">
<xsl:with-param name="status" select="'outstanding'"/>
<xsl:with-param name="dueAmount" select="$diff"/>
<xsl:with-param name="receipt" select="$latestReceiptForDeposit"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:template>
<xsl:template match="Deposits" mode="addAttrs">
<xsl:param name="status"/>
<xsl:param name="dueAmount"/>
<xsl:param name="receipt" select="''"/>
<!-- Constract a new MultiDeposits element with required info -->
<xsl:copy>
<xsl:copy-of select="./@*"/>
<xsl:attribute name="Status"><xsl:value-of select="$status"/></xsl:attribute>
<xsl:attribute name="DueAmount"><xsl:value-of select="$dueAmount"/></xsl:attribute>
<xsl:if test="$receipt">
<xsl:attribute name="latestReceiptDate">
<xsl:value-of select="$receipt/@ActionDate"/>
</xsl:attribute>
</xsl:if>
<xsl:copy-of select="./*"/>
</xsl:copy>
</xsl:template>
@Welbog謝謝你,看到它在僞使得它更清晰這是怎麼回事。我認爲包含聲明的if語句可用作基本情況?分行會繼續撥打同一套存款或不包括第一張存款。但是選擇聲明只有在有存款需要處理時纔會執行。 對不起,如果這是一個愚蠢的問題,只是試圖讓我的頭。 –
DashaLuna
2010-04-19 16:24:24
''部件不在您傳遞給模板的參數上運行。我假設它是某種全局變量。這絕對不是參與函數的基本情況,因爲一旦模板被第一次調用,'$ deposits'的值不會改變。如果它匹配第一個呼叫,它將匹配每個後續呼叫。 –
Welbog
2010-04-19 16:26:52
哦,是的,抱歉,這是一個錯字。它應該是。它不會無限循環。儘管如此,它並沒有正確計算DueAmount,我完全搞不懂爲什麼.. :(我應該編輯原始消息,尋求邏輯幫助或添加評論嗎? –
DashaLuna
2010-04-19 16:30:39