Jump to content

Xsl Recursion Force Quit


Den-J

Recommended Posts

Hi all, I have a problem with xsl and recursions..My input is a html file, I use xsl 1.0. My goal is to sum up fields (<td>) from a html table if a condition is true. The problem: The function calls itself after it was at the xsl:otherwise statement (please look at totalPackages function) E.g. I have 10 fields where on three fields the conditions fits(<xsl:if test = "number($bweight[$i]) = '0'" > <xsl:if test = "number($nweight[$i]) = '0'" >)The sum should be e.g. 10 + 6 + 12 = 28 As result I get = 28282828 After debugging with xml spy I found out that the recursion calls itself after the xsl:otherwise statement, I don't get it, after the otherwise statement and no call:template statement the function should be finished.. Has someone an idea? here is my code :

<xsl:template name="totalPackages">  <xsl:param name="summe" select="0"/>  <xsl:param name="amount"  />  <xsl:param name="bweight" />  <xsl:param name="nweight" />  <xsl:param name="i" select="1" />   <xsl:choose>    <xsl:when test="$bweight[$i]"> 	<xsl:if test = "number($bweight[$i]) = '0'" >	 <xsl:if test = "number($nweight[$i]) = '0'" >	  	  <xsl:call-template name="totalPackages">	   <xsl:with-param name="summe" select="number($summe) + number($amount[$i])" />	   <xsl:with-param name="i" select="$i + 1" />	   <xsl:with-param name="bweight" select="$bweight" />	   <xsl:with-param name="nweight" select="$nweight" />	   <xsl:with-param name="amount" select="$amount" />	  </xsl:call-template>	  	 </xsl:if>	</xsl:if> 	<xsl:if test = "number($bweight[$i]) > '0'" >		 <xsl:call-template name="totalPackages">	  <xsl:with-param name="summe" select="number($summe)" />	  <xsl:with-param name="i" select="$i + 1" />	  <xsl:with-param name="bweight" select="$bweight" />	  <xsl:with-param name="nweight" select="$nweight" />	  <xsl:with-param name="amount" select="$amount" />	 </xsl:call-template>		</xsl:if> 	<xsl:if test = "number($nweight[$i]) > '0'" >		 <xsl:call-template name="totalPackages">	  <xsl:with-param name="summe" select="number($summe)" />	  <xsl:with-param name="i" select="$i + 1" />	  <xsl:with-param name="bweight" select="$bweight" />	  <xsl:with-param name="nweight" select="$nweight" />	  <xsl:with-param name="amount" select="$amount" />	 </xsl:call-template>		</xsl:if>	     </xsl:when>    <xsl:otherwise>	<xsl:value-of select="$summe" />   </xsl:otherwise>   </xsl:choose></xsl:template>

<td>	<b>	 <xsl:call-template name="totalPackages">	  <xsl:with-param name="amount" select="//tr/td[@id = 'amount']" />	  <xsl:with-param name="bweight" select="//tr/td[@id = 'bweight']" />	  <xsl:with-param name="nweight" select="//tr/td[@id = 'nweight']" />	 </xsl:call-template>	</b>   </td>

Link to comment
Share on other sites

If you have a problem with some code then it is best to show us minimal but complete details to allow us to reproduce the problem easily. So at least show us an input sample you are trying to process.When reading your XSLT code it looks as if you simply call your template several times in all those xsl: if branches.

Link to comment
Share on other sites

The input but like pseudo code:

<html><head><title>Hi world !</title></head><body><form name="Form1" method="post"  action="some stuff"  id="Form1">  <p></p>  <table width="900px" cellspacing="2" cellpadding="1" border="0">   <tr>    <td id="1" width="40px">a ball</td>    <td id="2" width="40px">a pin</td>    <td id="3" width="*">a sword</td>    <td id="4" width="*"> </td>    <!--some comment-->    <!--some comment-->    <!--some comment-->    <td id="amount" width="75px" class="r">6</td>    <td id="5" width="75px" class="r">a date like 11.07.2001</td>    <!--some comment-->    <!--some comment-->    <td id="6" width="75px">378_</td>    <!--some comment-->    <!--some comment-->    <!--some comment-->    <td id="bweight" width="*">0</td>    <td id="nweight" width="*">0</td>    <td id="7" width="*">0</td>   </tr>     <tr>    The same stuff like before with other data   </tr>     <tr>    The same stuff like before with other data   </tr>     <tr>    The same stuff like before with other data   </tr>     <tr>    The same stuff like before with other data   </tr>     <tr>    The same stuff like before with other data   </tr>  </table>  <p></p></form></body></html>

Link to comment
Share on other sites

When reading your XSLT code it looks as if you simply call your template several times in all those xsl: if branches.
Well yes, I do recursion because I cannot do a for loop with xsl like
for i = 1; last element of bweight ; i++	 do that and thatend loop

I want to count the amount node when bweight and nweight is zero. I have a counter $i for accessing each node like in a for loop

Link to comment
Share on other sites

So I took your samples trying to create a test case to reproduce the problem, the XML input sample is the one you posted i.e.

<html><head><title>Hi world !</title></head><body><form name="Form1" method="post"  action="some stuff"  id="Form1">  <p></p>  <table width="900px" cellspacing="2" cellpadding="1" border="0">   <tr>    <td id="1" width="40px">a ball</td>    <td id="2" width="40px">a pin</td>    <td id="3" width="*">a sword</td>    <td id="4" width="*"> </td>    <!--some comment-->    <!--some comment-->    <!--some comment-->    <td id="amount" width="75px" class="r">6</td>    <td id="5" width="75px" class="r">a date like 11.07.2001</td>    <!--some comment-->    <!--some comment-->    <td id="6" width="75px">378_</td>    <!--some comment-->    <!--some comment-->    <!--some comment-->    <td id="bweight" width="*">0</td>    <td id="nweight" width="*">0</td>    <td id="7" width="*">0</td>   </tr>    <tr>    The same stuff like before with other data   </tr>    <tr>    The same stuff like before with other data   </tr>    <tr>    The same stuff like before with other data   </tr>    <tr>    The same stuff like before with other data   </tr>    <tr>    The same stuff like before with other data   </tr>  </table>  <p></p></form></body></html>

then I created a minimal stylesheet with your named template and its call:

<xsl:stylesheet  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="1.0"> <xsl:template name="totalPackages">  <xsl:param name="summe" select="0"/>  <xsl:param name="amount"  />  <xsl:param name="bweight" />  <xsl:param name="nweight" />  <xsl:param name="i" select="1" />   <xsl:choose>    <xsl:when test="$bweight[$i]"> 	    <xsl:if test = "number($bweight[$i]) = '0'" >		 <xsl:if test = "number($nweight[$i]) = '0'" >		  		  <xsl:call-template name="totalPackages">		   <xsl:with-param name="summe" select="number($summe) + number($amount[$i])" />		   <xsl:with-param name="i" select="$i + 1" />		   <xsl:with-param name="bweight" select="$bweight" />		   <xsl:with-param name="nweight" select="$nweight" />		   <xsl:with-param name="amount" select="$amount" />		  </xsl:call-template>		  		 </xsl:if>	    </xsl:if> 	    <xsl:if test = "number($bweight[$i]) > '0'" >	    		 <xsl:call-template name="totalPackages">		  <xsl:with-param name="summe" select="number($summe)" />		  <xsl:with-param name="i" select="$i + 1" />		  <xsl:with-param name="bweight" select="$bweight" />		  <xsl:with-param name="nweight" select="$nweight" />		  <xsl:with-param name="amount" select="$amount" />		 </xsl:call-template>	    	    </xsl:if> 	    <xsl:if test = "number($nweight[$i]) > '0'" >	    		 <xsl:call-template name="totalPackages">		  <xsl:with-param name="summe" select="number($summe)" />		  <xsl:with-param name="i" select="$i + 1" />		  <xsl:with-param name="bweight" select="$bweight" />		  <xsl:with-param name="nweight" select="$nweight" />		  <xsl:with-param name="amount" select="$amount" />		 </xsl:call-template>	    	    </xsl:if>	        </xsl:when>    <xsl:otherwise>	    <xsl:value-of select="$summe" />   </xsl:otherwise>   </xsl:choose></xsl:template><xsl:template match="/"><xsl:call-template name="totalPackages">		  <xsl:with-param name="amount" select="//tr/td[@id = 'amount']" />		  <xsl:with-param name="bweight" select="//tr/td[@id = 'bweight']" />		  <xsl:with-param name="nweight" select="//tr/td[@id = 'nweight']" />		 </xsl:call-template></xsl:template></xsl:stylesheet>

When I use Saxon 6.5.5 to apply the stylesheet to the sample document I get the output

<?xml version="1.0" encoding="utf-8"?>6

So at least with that input sample I am not able to see a wrong result, you should post minimal samples to allow us to reproduce the problem. As a wild guess however I wonder whether you really need a named template, can't you simply do e.g.

<xsl:value-of select="sum(//tr[td[@id = 'bweight'] = 0 and td[@id = 'nweight'] = 0]/td[@id = 'amount'])"/>

? That would be my XPath representation of your English description "I want to count the amount node when bweight and nweight is zero".

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...