Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

XML Sum and Loops

Status
Not open for further replies.

GavinP1983

Programmer
Aug 31, 2005
6
GB
I didn't really explain my problem well in the previous post so I thought I'd try again.

My stylesheet is:

Code:
<?xml version="1.0" encoding="ISO-8859-1"?><xsl:stylesheet version="1.0"
xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform"><xsl:template[/URL] match="/">
  <html>
  
  <body>
  
 <xsl:variable name="runningtotal">0</xsl:variable>
  
  
<hr />
<h1>List of Individual Stores:</h1>
<h2>Yeovil:</h2>
	<table border="1" width="100%" id="table1">
		<tr>
		
			<td><b>Sender</b></td>
			<td><b>Customer</b></td>
			<td><b>Address</b></td>
			<td><b>Gift</b></td>
			<td><b>Value</b></td>
		
			
			
		</tr>
		
		
		 
	<xsl:for-each select="NewDataSet/Table[Store='Yeovil']">
	
	<xsl:sort select="Store"/>
		
		<tr>
		
			<td><xsl:value-of select="Sender"/></td>
			<td><xsl:value-of select="Customer"/></td>
			<td><xsl:value-of select="Address"/></td>
			<td><xsl:value-of select="Gift"/></td>
			<td>£<xsl:value-of select="sum(Value)"/></td>

			<td></td>
		
				
		</tr>

	<p />   
	   
</xsl:for-each>


<td>Running total: 

// only want the total for yeovil, not everything

<xsl:value-of select="sum(NewDataSet/Table/Value)" />


</td>
<tr><td></td><td></td><td></td><td></td><td>

<b>

</b>

</td></tr>


</table>

<h1>Grand Total</h1>£<xsl:value-of select="sum(NewDataSet/Table/Value)" />

<hr />

  </body>
  </html>
</xsl:template></xsl:stylesheet>

My XML is:

Code:
<?xml version='1.0'?>
<?xml-stylesheet type="text/xsl" href="stylesheet.xsl"?>
<NewDataSet><Table><Year>2005</Year><Month>6</Month><Store>Bath</Store><Reason>Repair Issue</Reason><Sender>Ms Margaret Roberts</Sender><Customer>Miss Narissa Fish</Customer><Address>48  Warminster Road,
Westbury
Wilts
 BA13 3PF</Address><Gift>O1008 - Starlight Bouquet</Gift><Value>31.4700</Value></Table><Table><Year>2005</Year><Month>6</Month><Store>Bluewater</Store><Reason>Customer Service</Reason><Sender>Ms Gina Bonner</Sender><Customer>Mrs  Marshall</Customer><Address>the pines
35 rowanwood avenue
the hollies
sidcup da158wl</Address><Gift>O7309 - Semillon Chardonnay - Sacred Hill</Gift><Value>14.4900</Value></Table><Table><Year>2005</Year><Month>6</Month><Store>Bluewater</Store><Reason>Billing Issue</Reason><Sender>Ms Gina Bonner</Sender><Customer>Mr David  HALLS</Customer><Address>4, HOWELLS CLOSE
WEST KINGSDOWN
SEVENOAKS 
KENT TN15 6EE</Address><Gift>O7309 - Semillon Chardonnay - Sacred Hill</Gift><Value>14.4900</Value></Table>...</NewDataSet>

It's not the best, but I'm new so please bear with me. Basically, the Stylesheet reads in the customer data from the XML file but I can't get it to arrange properly.

I'd like to arrange everyone by store. For example, I'd like everyone who visited the store in 'Yoevil' to be in the same table. I've done this a crude way - I've actually specified the store name as you'll see. This works, but it's not brilliant because the store could change at any time (<store>Yeovil</store>). I know I need some sort of loop or XPath but I'm having trouble getting my head round it!

Secondly, I'm able to display the total value of the <value> fields, which is great but I need a sub total for each store. I've tried variables and incrementing them as <value> is iterated but I still can't get that to work either!

The final thing should be something like:

Store: Yeovil

Customer Name | Details | Value

Sub total: (value)

Store: Next Store

Customer Name | Details | Value

Sub total: (value)

Grand total: (value + value)

Any help much appreciated!
 
Try this:
Code:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform">[/URL]
  <xsl:template match="/">
    <html>
      <head>
        <title>XML Sum and Loops</title>
        <style type="text/css">
caption
{
  font-size: large;
  font-weight: bold;
  text-align: left;
}
      </style>
      </head>
      <body>
        <xsl:apply-templates select="NewDataSet/Table[not(Store = preceding-sibling::Table/Store)]" mode="Store"/>
        <div style="width: 100%; text-align: right;">
          <h2>
            <xsl:value-of select="concat('Grand Total: ', sum(NewDataSet/Table/Value))"/>
          </h2>
        </div>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="Table" mode="Store">
    <table border="1" width="100%" summary="Invoice table for {Store} store">
      <caption>
        <xsl:value-of select="concat('Store: ', Store)"/>
      </caption>
      <thead>
        <tr>
          <th>Sender</th>
          <th>Customer</th>
          <th>Address</th>
          <th>Gift</th>
          <th>Value</th>
        </tr>
      </thead>
      <tfoot>
        <tr>
          <th colspan="4" align="right">Subtotal:</th>
          <th>
            <xsl:value-of select="sum(../Table[Store = current()/Store]/Value)"/>
          </th>
        </tr>
      </tfoot>
      <tbody>
        <xsl:apply-templates select="../Table[Store = current()/Store]" mode="Details"/>
      </tbody>
    </table>
  </xsl:template>
  <xsl:template match="Table" mode="Details">
    <tr>
      <td>
        <xsl:value-of select="Sender"/>
      </td>
      <td>
        <xsl:value-of select="Customer"/>
      </td>
      <td>
        <xsl:value-of select="Address"/>
      </td>
      <td>
        <xsl:value-of select="Gift"/>
      </td>
      <td>
        <xsl:value-of select="Value"/>
      </td>
    </tr>
  </xsl:template>
</xsl:stylesheet>

Jon

"I don't regret this, but I both rue and lament it.
 
Thanks for your help. If I wanted to organise it by date, eg:

2005

6/2005

Bluewater

details as before

Bath

details as before


8/2005

Bluewater

details as before

Yoevil

details as before

==========================================

Grand total for 2005: xx

How would I go about that? This XPath confuses me, I've only just got the hang of XML
 
Is anyone able to help? I'm trying various tutorials and I'm learning new things all the time, but this is a little advanced.

The solution is about complete, as I said, it's the same as the solution JontyMC kindly provided, but rather than organising by Store alone, customers need to be organised into stores by the date and month. I'm guessing it needs some sort of 'nested template'? - so that dates are arranged and within the dates, customers are arranged as before but by Store (like the above example), with a total for each store and for each month and year, with a grand total like before?

Any help is much appreciated.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top