XML Editor
Sign up for a WebBoard account Sign Up Keyword Search Search More Options... Options
Chat Rooms Chat Help Help News News Log in to WebBoard Log in Not Logged in
Show tree view Topic
Topic Page 1 2 3 4 5 6 7 8 9 Go to previous topicPrev TopicGo to next topicNext Topic
Postnext
Steven MatthewsSubject: keeping track of data
Author: Steven Matthews
Date: 01 May 2006 04:40 AM
Hi There,

I am using XSLT to format an XML file called orders.xml
I need to collect together the 'invoices_rec' elements for each customer with the same invoiceNum. I am using a loop but I need to find a way to
save the last invoice number in order to see if it has changed, so that I can compare it with the new invoiceNum.

I am using this variable:
<xsl:variable name="last_invoice_number" select="invoices/invoices_rec/invoiceNum"/>

I am using this test but it does not work:
<!-- Check that invoiceNum has changed -->
<xsl:if test="invoiceNum != $last_invoice_number">
code here
</xsl:if>

HERE IS THE FULL SOURCE CODE:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/database">
<html>
<body>
<h2>All Customer Invoices</h2>
<title>All Customer Invoices</title>

<!-- display FIRST customer details -->
<p />Ship to:<br/><br/>
<p /><xsl:value-of select="invoices/invoices_rec/contactName"/><br />
<xsl:value-of select="invoices/invoices_rec/shipToAddress"/><br />
<xsl:value-of select="invoices/invoices_rec/shipToCity"/><br />
<xsl:value-of select="invoices/invoices_rec/shipToState"/><br />
<xsl:value-of select="invoices/invoices_rec/shipToZip"/><br />

<!-- display FIRST customer invoice details -->
<br/><p />INVOICE NUMBER: <xsl:value-of select="invoices/invoices_rec/invoiceNum"/>
<p />SALES DATE: <xsl:value-of select="invoices/invoices_rec/salesDate"/><br/><br/>

<!-- Capture and store FIRST invoiceNum -->
<xsl:variable name="last_invoice_number" select="invoices/invoices_rec/invoiceNum"/>

<!-- display table headers -->
<table border="1">
<tr bgcolor="#9acd32">
<th>Product ID</th>
<th>Product Name</th>
<th>Product Description</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Extended Price</th>
</tr>

<!-- Start main loop here -->
<xsl:for-each select="invoices/invoices_rec">

<!-- Check that customer has changed -->
<xsl:if test="invoiceNum != $last_invoice_number">

<!-- display NEW customer details, since new customer -->
<p />Ship to:<br/><br/>
<p /><xsl:value-of select="contactName"/><br />
<xsl:value-of select="shipToAddress"/><br />
<xsl:value-of select="shipToCity"/><br />
<xsl:value-of select="shipToState"/><br />
<xsl:value-of select="shipToZip"/><br />

<!-- display NEW customer invoice details -->
<br/><p />INVOICE NUMBER: <xsl:value-of select="invoiceNum"/>
<p />SALES DATE: <xsl:value-of select="salesDate"/><br/><br/>

<!-- display new table headers -->
<table border="1">
<tr bgcolor="#9acd32">
<th>Product ID</th>
<th>Product Name</th>
<th>Product Description</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Extended Price</th>
</tr>
</table>

<!-- Store last invoiceNum -->
<xsl:for-each select="invoiceNum">
<xsl:variable name="last_invoice_number" select="."/>
</xsl:for-each>

</xsl:if>

<!-- display PRODUCT details in a table -->
<tr>
<td><xsl:value-of select="ProductID"/></td>
<td><xsl:value-of select="ProductName"/></td>
<td><xsl:value-of select="ProductDescription"/></td>
<td><xsl:value-of select="Quantity"/></td>
<td><xsl:value-of select="UnitPrice"/></td>
<td><xsl:value-of select="ExtendedPrice"/></td>
</tr>

</xsl:for-each>

<!-- Close last table -->
</table><br/><br/>

</body>
</html>

</xsl:template>
</xsl:stylesheet>

Any help would be appreciated,

regards,

Steven Matthews


Documentorders.xml
XML

Postnext
Ivan PedruzziSubject: keeping track of data
Author: Ivan Pedruzzi
Date: 01 May 2006 10:04 AM
Hi Steven,

This is a basic grouping problem, please use the attached solution to guide you in the right direction.

Hope this helps
Ivan Pedruzzi
Stylus Studio Team


Documentorders(1).xsl

Postnext
Steven MatthewsSubject: keeping track of data
Author: Steven Matthews
Date: 01 May 2006 02:22 PM
Thanks Ivan,

That really does work ! I spent two hours trying to figure out how to fix it and eventually gave up !

I am a newbie to XSL (as you can tell !), coming from a C/C++ background. It would seem that the logic with XSL is quite different from that in traditional programming languages. I have been trying to use that same programming logic with XSL !

One question, what does this condition actually mean:

<xsl:for-each select="invoices/invoices_rec[ generate-id(.) = generate-id( key('invoiceid', invoiceNum)[1])]"> ??

I really would like to know what is going on here ..

Thanks again for all the help

Steven Matthews, UK

Posttop
Ivan PedruzziSubject: keeping track of data
Author: Ivan Pedruzzi
Date: 01 May 2006 02:54 PM

That's grouping technique called Muenchian

1) I defined a key (it works like a hashmap in C++), so i can look-up an invoices_rec by invoiceNum

<xsl:key name="invoiceid" match="/database/invoices/invoices_rec" use="invoiceNum"/>

2) I iterate on each invoices_rec but only considreing the first one in the group (group by invoiceNum)

xsl:for-each select="invoices/invoices_rec[ generate-id(.) = generate-id( key('invoiceid', invoiceNum)[1])]">

invoices/invoices_rec[ ]
The expression inside the square brackets gets evaluated for each invoices_rec

key('invoiceid', invoiceNum)[1]
This returns a list of invoices_rec given invoiceNum in the context,
I take the first one.

generate-id
Returns a unique id for a given node that be used to check if two expressions are selecting the same node.


Here you can find several other technique
http://www.dpawson.co.uk/xsl/sect2/N4486.html

Hope this helps
Ivan Pedruzzi
Stylus Studio Team

 
Topic Page 1 2 3 4 5 6 7 8 9 Go to previous topicPrev TopicGo to next topicNext Topic
Download A Free Trial of Stylus Studio 6 XML Professional Edition Today! Powered by Stylus Studio, the world's leading XML IDE for XML, XSLT, XQuery, XML Schema, DTD, XPath, WSDL, XHTML, SQL/XML, and XML Mapping!  
go

Log In Options

Site Map | Privacy Policy | Terms of Use | Trademarks
Stylus Scoop XML Newsletter:
W3C Member
Stylus Studio® and DataDirect XQuery ™are from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2016 All Rights Reserved.