none
XSLT logic : NaN in output, need 0

    Question

  •  <Total>          
            
                 <xsl:choose>
                        <xsl:when test="$SeqNumber != 1 and $SeqNumber != 5 ">
                            <xsl:value-of select="format-number(sum(//Details[(SenderNumber = $SNumber) and (SequenceNumber = $SeqNumber)]/LineSubTotal/text()) div sum(//Details[(SenderNumber = $SNumber) and (SequenceNumber = $SeqNumber)]/Qty/text()),'0.####') " />
                        </xsl:when>
                   
                        
                        <xsl:otherwise>
                            <xsl:value-of select="sum(//Details[(SenderNumber = $SNumber) and (SequenceNumber = $SeqNumber)]/Price/text())" />
                        </xsl:otherwise>
                    </xsl:choose>
                    
            </Total>

    Basically I need 1%0 = 0 (forcefully I want this logic)



    The issue I am facing is if 'LineSubTotal' is zero or empty or 'Qty' is empty then I am receiving NaN.
    Whenever I receive NaN, I need to output as '0'
    How can I acheive this ?



    Reason101




    • Edited by Reason101 Friday, April 28, 2017 10:14 PM a
    Friday, April 28, 2017 6:46 PM

All replies

  • NaN = Not A Numeric

    You need to check that all data in your calculations are indeed numeric
    Could also be caused by division by zero IIRC

    If you can provide source xml documents it's possible to work out the issue

    rgds

    Friday, April 28, 2017 10:17 PM
  • I basically need 1/0 = 0, empty by empty = 0

    In 1st record I have valid LineSubTotal and Qty that gives me valid output 
    In 2nd record, LineSubTotal is 0, and Qty doesnt exist ----> still I need 0 output
    In 3rd record, No LineSubTotal and No Qty   ----> still I need 0 output

    <Details>
    		<LineSubTotal>123</LineSubTotal>
    		<Price>96.6400</Price>
    		<SequenceNumber>3</ComponentSequenceNumber>
    		<SenderNumber>101</SenderNumber>
    		<Qty>12</Qty>
    </Details>
    <Details>
    		<LineSubTotal>0</LineSubTotal>
    		<Price>96.6400</Price>
    		<SequenceNumber>2</ComponentSequenceNumber>
    		<SenderNumber>102</SenderNumber>
    		
    </Details>
    <Details>
    		
    		<Price>96.6400</Price>
    		<SequenceNumber>3</ComponentSequenceNumber>
    		<SenderNumber>103</SenderNumber>
    		
    </Details>


    Reason101

    Friday, April 28, 2017 10:30 PM
  • Hi

    So before performing the arithmetic operation you have to check the operand values in XSLT, use <xsl:choose> and <xsl:when>/<xsl:otherwise> to conditionally check first for the operand value(whether 0 or not).  If 0, store 0 in a variable - do this in the <xsl:when> block.

    If not 0, do the division and store the results in the same variable in the <xsl:otherwise> block.

    Outside the <xsl:choose>, assign the variable value to the element you are calculating.


    Thanks Arindam


    Saturday, April 29, 2017 3:13 AM
    Moderator
  • I already tried that, please see my first post. Can you suggest logic to that ?

    Reason101

    Saturday, April 29, 2017 3:46 AM
  • <Total> <xsl:choose> <xsl:when test="$SeqNumber != 1 and $SeqNumber != 5 ">

    <xsl:choose>

    <xsl:when test="

    format-number(sum(//Details[(SenderNumber = $SNumber) and (SequenceNumber = $SeqNumber)]/LineSubTotal/text()) div sum(//Details[(SenderNumber = $SNumber) and (SequenceNumber = $SeqNumber)]/Qty/text()),'0.####') 

    !=NaN"

    <xsl:value-of select="format-number(sum(//Details[(SenderNumber = $SNumber) and (SequenceNumber = $SeqNumber)]/LineSubTotal/text()) div sum(//Details[(SenderNumber = $SNumber) and (SequenceNumber = $SeqNumber)]/Qty/text()),'0.####') " /> <xsl:otherwise>

    <xsl:value-of select="'0'"/>

    </xsl:otherwise>

    </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:value-of select="sum(//Details[(SenderNumber = $SNumber) and (SequenceNumber = $SeqNumber)]/Price/text())" /> </xsl:otherwise> </xsl:choose> </Total>


    Pi_xel_xar

    Blog: My Blog

    BizTalkApplicationDeploymentTool: BizTalk Application Deployment Tool/

    Saturday, April 29, 2017 6:02 AM
    Answerer
  • Its always good to check the input parameters for its number authenticity before it is used in arithmetic operations

    Also, NaN may occur even if the variable is null, its good to disguise NaN as 0 at the output.

    Please check the below links for more details

    http://www.verycomputer.com/36_647c59b52b311cb7_1.htm 

    https://www.webmasterworld.com/forum26/44.htm 


    Regards, Vignesh S

    Saturday, April 29, 2017 3:17 PM
  • <Total>       
    	
    	<xsl:choose>
    	  <xsl:when test="$SeqNumber != 1 and $SeqNumber != 5 ">
    	     <xsl:choose>
    		
    	        <xsl:when test="format-number(sum(//Details[(SenderNumber = $VNumber) and (SequenceNumber = $SeqNumber)]/LineSubTotal/text()) div sum(//Details[(SequenceNumber = $VNumber) and (SequenceNumber = $SeqNumber)]/Qty/text()),'0.####')!='NaN'">
    			<xsl:value-of select="format-number(sum(//Details[(SenderNumber = $VNumber) and (SequenceNumber = $SeqNumber)]/LineItemSubTotal/text()) div sum(//Details[(SenderNumber = $VNumber) and (SequenceNumber = $SeqNumber)]/Qty/text()),'0.####') " />
                     </xsl:when>
    			     <xsl:otherwise>
                                    <xsl:value-of select="'0'"/>
                                 </xsl:otherwise>
                    
                 </xsl:choose>   
            
    	       </xsl:when>
    		<xsl:otherwise>
    			<xsl:value-of select="sum(//Details[(SenderNumber = $VNumber) and (SequenceNumber = $SeqNumber)]/Price/text())" />
    		</xsl:otherwise>
    	</xsl:choose>
    
    							   
    </Total>
    the above logic I tried, its giving all 0 in all LineItems for Total field

    Reason101

    Sunday, April 30, 2017 5:57 AM
  • So, this is relatively easy to do in the Mapper.  Is it too late to not use Xslt?  As I've mentioned before, using Xslt, presumably due to the Sequence number, is adding a lot of unnecessary complication.

    Sunday, April 30, 2017 12:47 PM
    Moderator
  • You are trying a little too hard 

    Create a nodeset variable without records where linesumtotal is not empty or eq 0 and qty is not empty

    You can the calculate the sum over the nodeset variable

    The mapper with loop through all detail nodes using a whole bunch of C# scripting functions

    This will get all nodes where qty exists and qty greater than 0

    /Document/Details[Qty>0]

    rgds /Peter



    Sunday, April 30, 2017 3:19 PM