[KLUG Members] XSLT Transforms

Adam Williams members@kalamazoolinux.org
09 Jan 2003 14:01:27 -0500


Mr. Holland sent me a basic XSLT file that transformed the salesperson
and customer data into a nice HTML file.  I added code for the elements
below customer, but unfortunately the formatting is kind of gnarly.

I've looked about for a way to only include the header for customer
discount entries if there are any (essentially an "if").  I've found
code for doing counts, etc... but no obvious examples of how to properly
create nested tables.

<?xml version="1.0"?>
<!-- 
<customer_price_matrix_report>
  <salesperson name="" mail="" customercount="0"/>
  <salesperson name="" mail="" customercount="41">
    <customer name="1ST AYD CORPORATION" company="ME"
      number="10225" city="ELGIN" state="IL"/>
     <customer name="ASC INCORPORATED" company="ME"
       number="10421" city="SOUTHGATE" state="MI"/>
     <customer name="CITY OF STURGIS" company="ME"
       number="10268" city="STURGIS" state="MI">
        <oem_discount oem="" captive="1.1" noncaptive="1.0"
         user="sswonk    " date="2001-03-20 12:09"/>
       <oem_discount oem="AAA" captive="1.0" noncaptive="1.0"
         user="sswonk    " date="2001-03-20 12:09"/>
      </customer>
-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


  <xsl:output method="html"/>

  <xsl:template match="/customer_price_matrix_report">
	<html>
	<head>
	</head>
	<body>
	<xsl:apply-templates/>
	</body>
	</html>
  </xsl:template>

  <xsl:template match="salesperson">
	<h2><xsl:value-of select="@name"/></h2>
    <table>
	  <tr>
	    <th align="center" valign="bottom">Customer<br/>name</th>
	    <th align="center" valign="bottom">Company<br/>Code</th>
	    <th align="center" valign="bottom">Customer's<br/>City</th>
	    <th align="center" valign="bottom">Customer's<br/>State</th>
      </tr>   
	  <xsl:apply-templates/>
	</table>
  </xsl:template>

    <xsl:template match="customer">
	<tr>
        <td><xsl:value-of select="@name"/></td>
        <td><xsl:value-of select="@company"/></td>
        <td><xsl:value-of select="@city"/></td>
        <td><xsl:value-of select="@state"/></td>
	</tr>
	<tr>
	    <td align="center" colspan="4">Customer OEM Discounts</td>
	</tr>
	<tr>
	    <td align="center" colspan="4">
	      <table>
	        <tr>
	           <th align="center" valign="bottom">OEM</th>
	           <th align="center" valign="bottom">Captive<br/>Discount</th>
	           <th align="center" valign="bottom">Non-Captive<br/>Discount</th>
	           <th align="center" valign="bottom">User<br/>Id</th>
	           <th align="center" valign="bottom">Update<br/>Date</th>
	        </tr>
  	      <xsl:apply-templates/>
  	    </table>
  	  </td>
    </tr>
    </xsl:template>

    <xsl:template match="oem_discount">
       <tr>
         <td><xsl:value-of select="@oem"/></td>
         <td><xsl:value-of select="@captive"/></td>
         <td><xsl:value-of select="@noncaptive"/></td>
         <td><xsl:value-of select="@user"/></td>
         <td><xsl:value-of select="@date"/></td>
       </tr>
    </xsl:template>

   <xsl:template match="text()|@*"/>

</xsl:stylesheet>

I realize an "if" isn't quite what I want as this isn't a 
procedural thing, but a "state" one.  Basically if I could 
move the headers inside the "<xsl:template match="oem_discount">" and 
only have them appear once?