Chris Kettenbach wrote:
> Good Morning,
> Sorry for xposting. Just need a liitle help.
> I have an xml file that's generated from a database. How do I select
> distinct values from a field
XML doesn't have fields -- the database did but this isn't a database any
more. In XML they're called elements (they've got a lot in common with
fields but they ain't the same).
> in xslt and then loop through the records and
> produce output.
It looks like you need to process the information grouped by company name,
and there's a technique in XSLT 1.0 for doing this called Muenchian grouping
(it won't be needed in XSLT 2 because that has a built-in group-processing
command, but XSLT 2 is not a Recommendation yet).
Check the XSLT FAQ for "Muenchian" to find examples.
///Peter
[Group and followup corrected to comp.text.xml]
> Example
>
> <registrations>
> <registration>
> <company>Awesome Printers</company>
> <first>John</first>
> <last>Smith</last>
> </registration>
> <registration>
> <company>Awesome Printers</company>
> <first>Bob</first>
> <last>Roberts</last>
> </registration>
> <registration>
> <company>Awesome Printers</company>
> <first>John</first>
> <last>Johnson</last>
> </registration>
> <registration>
> <company>Other Company</company>
> <first>Tom</first>
> <last>Thomas</last>
> </registration>
> <registration>
> <company>Other Company</company>
> <first>Dan</first>
> <last>Daniels</last>
> </registration>
> </registrations>
> ++++++++++++++++++++++++++++++++++++++++++++++++
> I want the out put to be something like this
>
> <table>
> <tr>
> <td>Company Name</td>
> <td>Employees</td>
> </tr>
> <tr>
> <td>Awesome Printers</td>
> <td>John Smith<br/>
> Bob Roberts<br/>
> John Johnson<br/></td>
> </tr>
> <tr>
> <td>Other Company</td>
> <td>Tom Thomas<br/>
> Dan Daniels<br/></td>
> </tr>
> </table>
>
> Effectively writing unique company names once and then putting only the
> employees from that company into the employee table cell.
If you scrolled down this far then you've been rewarded
The trick is to use lookup keys to test the selected group of elements
against, in order to pick only the first ocurrence in each group; then
output the group header at that point; and only then go and process all the
elements in the group to extract the detail from each of them.
The syntax is tricky because it's very compact. It selects all registration
elements, but subjects each of them to the test that [the number of nodes in
the union of (the current node and the first node with the current company
value returned by the lookup) is equal to 1] -- in effect meaning they are
one and the same node, ie the first in their company name grouping. You'll
probably need to read that 3 or 4 times -- it took me a week to grok it.
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns

sl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl

utput method="html"/>
<xsl:key name="entry" match="registration" use="company"/>
<xsl:template match="/">
<html>
<head>
<title>Registrations</title>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="registrations">
<table>
<xsl:for-each select="registration[count(.|key('entry',company
[1])=1]">
<xsl:sort select="company"/>
<tr>
<th valign="top">
<xsl:value-of select="company"/>
</th>
<td valign="top">
<xsl:for-each select="key('entry',current()/company)">
<xsl:sort select="last"/>
<xsl:value-of select="first"/>
<xsl:text> </xsl:text>
<xsl:value-of select="last"/>
<xsl:if test="position()!=last()">
<br/>
</xsl:if>
</xsl:for-each>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
///Peter