tags:

views:

850

answers:

2

Hi everyone,

I am having a problem trying to simply sum some values using XSLT. I a template online and have modified it for my needs. (link text)

No matter how I try, I cannot get the template to sum the numbers. I either end up with a total of "0" or a concatenation of the numbers I want summed. If someone could take a look and point out where I am going wrong, I would greatly appreciated it.

Thanks

** TEMPLATE **

print("<xsl:template match="Parts">
 <root>
  <xsl:variable name="tmpTotal">
   <total_amount>
    <xsl:for-each select="Part">
     <item>
      <xsl:value-of select="Duration"/>
     </item>
    </xsl:for-each>
   </total_amount>
  </xsl:variable>
  <total>
   <xsl:variable name="myTotal" select="number(msxsl:node-set($tmpTotal))" /> <!--Shows up as 0-->
   <xsl:value-of select="sum(msxsl:node-set($myTotal)/total_amount/item)" />
   <!--<xsl:variable name="myTotal" select="msxsl:node-set($tmpTotal)" />--> <!-- Shows up as concatenation-->
   <!--<xsl:value-of select="msxsl:node-set($myTotal)" />--> 
  </total>
 </root>
</xsl:template>");

** XML **

print("<Parts>
<Part>
  <PartNum>0000-A123</PartNum> 
  <Rate>0</Rate> 
  <Rate0Decimal>0</Rate0Decimal> 
  <ProductRemovedNumber>...</ProductRemovedNumber> 
  <Qty>2</Qty> 
  <Resolution>False</Resolution> 
  <ReturnFA>False</ReturnFA> 
  <SerialNumber /> 
  <TickProblemCD>15</TickProblemCD> 
  <TicketNum>075020009000048</TicketNum> 
  <Total>0</Total> 
  <Total0Decimal>0</Total0Decimal> 
  <TotalDisplay>0</TotalDisplay> 
  <UserNumber>009</UserNumber> 
  </Part>
<Part>
  <Duration>2</Duration>
  <Total>0</Total> 
  <PartCost>0.00</PartCost> 
  <PartCost0Decimal>0</PartCost0Decimal> 
  <PerformedBy>TEST</PerformedBy> 
  <WorkDoneCode /> 
  <WorkDoneDesc /> 
  <ZoneBasedTravel>False</ZoneBasedTravel> 
  <PartNum>Travel</PartNum> 
  <PartDescr>---</PartDescr> 
  <Qty>2</Qty> 
  </Part>
<Part>
  <Duration>4</Duration> 
  <DurationRequired>True</DurationRequired> 
  <EndTime>12/4/2008 2:24 PM</EndTime> 
  <EndTimeOnly>12/4/2008</EndTimeOnly> 
  <FamilyName>NON-COMPLAINT</FamilyName> 
  <FOC>False</FOC> 
  <InvTxnGenerated /> 
  <LastUpdatedDate>12/4/2008 2:24 PM</LastUpdatedDate> 
  <Rate>0</Rate> 
  <Rate0Decimal>0</Rate0Decimal> 
  <RateType>Install</RateType> 
  <Total>0</Total> 
  <PartCost>0.00</PartCost> 
  <PartCost0Decimal>0</PartCost0Decimal> 
  <PerformedBy>TEST</PerformedBy> 
  <WorkDoneCode>17000</WorkDoneCode> 
  <WorkDoneDesc>De-Installation / Instrument Move</WorkDoneDesc> 
  <ZoneBasedTravel>False</ZoneBasedTravel> 
  <PartNum>Labor</PartNum> 
  <PartDescr>Install</PartDescr> 
  <Qty>4</Qty> 
  </Part>
<Part>
  <Duration>1</Duration> 
  <DurationRequired>True</DurationRequired> 
  <EndTime>12/4/2008 2:24 PM</EndTime> 
  <EndTimeOnly>12/4/2008</EndTimeOnly> 
  <FamilyName>NON-COMPLAINT</FamilyName> 
  <FOC>False</FOC> 
  <InvTxnGenerated /> 
  <LastUpdatedDate>12/4/2008 2:24 PM</LastUpdatedDate> 
  <Rate>0</Rate> 
  <Rate0Decimal>0</Rate0Decimal> 
  <RateType>TSB/ISA</RateType> 
  <Total>0</Total> 
  <PartCost>0.00</PartCost> 
  <PartCost0Decimal>0</PartCost0Decimal> 
  <PerformedBy>TEST</PerformedBy> 
  <WorkDoneCode>13000</WorkDoneCode> 
  <WorkDoneDesc>TSB / ISA - Installed</WorkDoneDesc> 
  <ZoneBasedTravel>False</ZoneBasedTravel> 
  <PartNum>Labor</PartNum> 
  <PartDescr>TSB/ISA</PartDescr> 
  <Qty>1</Qty> 
  </Part>
  </Parts>");
+4  A: 

You do not explain exactly which are the values to be summed.

Judging from the presented XSLT code, it appears that you want the sum of the values of all "Duration" elements. This can be obtained using the following simple XPath expression:

   sum(/*/*/Duration)

Below is the complete XSLT transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>

    <xsl:template match="/">
      <xsl:value-of select="sum(/*/*/Duration)"/>
    </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the provided XML document:

<Parts>
    <Part>
     <PartNum>0000-A123</PartNum>
     <Rate>0</Rate>
     <Rate0Decimal>0</Rate0Decimal>
     <ProductRemovedNumber>...</ProductRemovedNumber>
     <Qty>2</Qty>
     <Resolution>False</Resolution>
     <ReturnFA>False</ReturnFA>
     <SerialNumber />
     <TickProblemCD>15</TickProblemCD>
     <TicketNum>075020009000048</TicketNum>
     <Total>0</Total>
     <Total0Decimal>0</Total0Decimal>
     <TotalDisplay>0</TotalDisplay>
     <UserNumber>009</UserNumber>
    </Part>
    <Part>
     <Duration>2</Duration>
     <Total>0</Total>
     <PartCost>0.00</PartCost>
     <PartCost0Decimal>0</PartCost0Decimal>
     <PerformedBy>TEST</PerformedBy>
     <WorkDoneCode />
     <WorkDoneDesc />
     <ZoneBasedTravel>False</ZoneBasedTravel>
     <PartNum>Travel</PartNum>
     <PartDescr>---</PartDescr>
     <Qty>2</Qty>
    </Part>
    <Part>
     <Duration>4</Duration>
     <DurationRequired>True</DurationRequired>
     <EndTime>12/4/2008 2:24 PM</EndTime>
     <EndTimeOnly>12/4/2008</EndTimeOnly>
     <FamilyName>NON-COMPLAINT</FamilyName>
     <FOC>False</FOC>
     <InvTxnGenerated />
     <LastUpdatedDate>12/4/2008 2:24 PM</LastUpdatedDate>
     <Rate>0</Rate>
     <Rate0Decimal>0</Rate0Decimal>
     <RateType>Install</RateType>
     <Total>0</Total>
     <PartCost>0.00</PartCost>
     <PartCost0Decimal>0</PartCost0Decimal>
     <PerformedBy>TEST</PerformedBy>
     <WorkDoneCode>17000</WorkDoneCode>
     <WorkDoneDesc>De-Installation / Instrument Move</WorkDoneDesc>
     <ZoneBasedTravel>False</ZoneBasedTravel>
     <PartNum>Labor</PartNum>
     <PartDescr>Install</PartDescr>
     <Qty>4</Qty>
    </Part>
    <Part>
     <Duration>1</Duration>
     <DurationRequired>True</DurationRequired>
     <EndTime>12/4/2008 2:24 PM</EndTime>
     <EndTimeOnly>12/4/2008</EndTimeOnly>
     <FamilyName>NON-COMPLAINT</FamilyName>
     <FOC>False</FOC>
     <InvTxnGenerated />
     <LastUpdatedDate>12/4/2008 2:24 PM</LastUpdatedDate>
     <Rate>0</Rate>
     <Rate0Decimal>0</Rate0Decimal>
     <RateType>TSB/ISA</RateType>
     <Total>0</Total>
     <PartCost>0.00</PartCost>
     <PartCost0Decimal>0</PartCost0Decimal>
     <PerformedBy>TEST</PerformedBy>
     <WorkDoneCode>13000</WorkDoneCode>
     <WorkDoneDesc>TSB / ISA - Installed</WorkDoneDesc>
     <ZoneBasedTravel>False</ZoneBasedTravel>
     <PartNum>Labor</PartNum>
     <PartDescr>TSB/ISA</PartDescr>
     <Qty>1</Qty>
    </Part>
</Parts>

The wanted result is produced:

7

Edit: In a comment the OP explained that he is looking to sum the Duration of all part-s whose PartNumber is equal to "Labor".

The following XPath expression produces this sum:

   sum(/*/*[PartNum='Labor']/Duration)

Dimitre Novatchev
+1, and should be be accepted answered. i was specifically looking for how to perform totals in xsl. But it looks like Dave closed his account.
Ian Boyd
A: 

Hi Dimitre,

Thanks for your response. Your example worked as expected. I want to sum up the duration like you used in the example above, however, I would like to be able to seperate it by the category in the < PartNum > tag. So for example only summing the values of parts that have < PartNum >Labor< / PartNum >. Is this possible?

Thanks

Yes, I edited my answer with the XPath expression that calculates this. You can accept the answer by clicking on the (white) checkmark near your question
Dimitre Novatchev