<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:set="http://exslt.org/set" version="1.0" extension-element-prefixes="set" set:doc="http://www.exslt.org/set" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
    <xsl:output encoding="utf-8" method="html" />
    <xsl:include href="style1.xsl"/>



	<!--
	The essence of using the variable to store our elements is very similar to a
	key table. In this solution, all products are put into the variable (which itself is
	in document order) -->
    <xsl:variable name="AllProducts" select="/"/>

	<!--
	The variable $AllRegions will be initialized with all of the distinct
	region elements.  This collection of nodes is created using the set:distinct
	template from EXSLT.org (see bottom) -->
    <xsl:variable name="AllRegionsDistinct">
    	   <xsl:call-template name="set:distinct">
         	  <xsl:with-param name="nodes" select="//products/product/region" />
        </xsl:call-template>
	</xsl:variable>
	
	<!--
	The variable $AllRegions, will hold the "nodeset" equivalent of the
	Result Tree Fragment generated by the "set:distinct template.  
	-->
	<xsl:variable name="AllRegions" select="msxsl:node-set($AllRegionsDistinct)"/>


	<!-- Template for root rule -->
    <xsl:template match="/">
	    	<xsl:call-template name="Style1"/>
		<h2>Grouping of Products by Region, then by Product Name </h2>
     	<xsl:apply-templates />
    </xsl:template>

	<!-- Template for products rule -->
    <xsl:template match="products">

		<!-- Iterate through the variable containing all of the unique regions -->
	    <xsl:for-each select="$AllRegions/region">
	    	<xsl:variable name="region" select="." /><BR></BR>

		    <H3>Region:    <xsl:value-of select="$region" /></H3>

    		<table border="1">
    			<tr>
    			<th>Product ID</th>
			    <th>Name</th>
			    <th>Price</th>
		 	    <th>Quantity</th>
		 	    <th>Region</th>
       			</tr>

			<!-- Grab the product elements that match the current retion.  At this point
			the products are retrived from our variable rather than the document itself -->
    		<xsl:for-each select="$AllProducts/products/product[region=$region]">
    			<xsl:sort select="name"/>
    			<tr>
    			<td><xsl:value-of select="prodid" /></td>
			    <td><xsl:value-of select="name" /></td>
			    <td><xsl:value-of select="price" /></td>
		 	    <td><xsl:value-of select="quantity" /></td>
		 	    <td><xsl:value-of select="region" /></td>

       			</tr>
    		</xsl:for-each>
    		</table>
    	</xsl:for-each>
    </xsl:template>

<!-- The following template was created by Jeni Tennison of                        -->
<!--  http://www.JeniTennison.com and is part of an extremely useful           -->
<!--  collection of extension functions and templates at http://www.exslt.org -->
    <xsl:template name="set:distinct">
        <xsl:param name="nodes" select="/.." />

        <xsl:choose>
            <xsl:when test="not($nodes)" />

            <xsl:otherwise>
                <xsl:copy-of select="$nodes[1][not(. = $nodes[position() &gt; 1])]" />

                <xsl:call-template name="set:distinct">
                    <xsl:with-param name="nodes" select="$nodes[position() &gt; 1]" />
                </xsl:call-template>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>


