Hi all,
I hope this doesn't further the decline in the quality of the questions
on xsl list too much, but here goes:
I've got xml that contains large lists of things. The uniqueness of an
item in the list is defined by the contents
of more than one child element. What I want to do is to create a table
of all of the unique items in the list.
So, for example, in a list of cars at auto dealerships, for each dealer,
I want to list the unique cars, where
unique is defined by the contents of all of <make> <model> and <year>:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="c:\myprojects\testdata\xslfiles\testfile.xsl"
type="text/xsl"?>
<carlist>
<dealership name="Fred's Used Cars">
<car>
<make>Chevy</make>
<model>Malibu</model>
<year>1979</year>
</car>
<car>
<make>Dodge</make>
<model>Charger</model>
<year>1979</year>
</car>
<!-- This one should get filtered out, because it is the same as the
first car in this dealers list-->
<car>
<make>Chevy</make>
<model>Malibu</model>
<year>1979</year>
</car>
</dealership>
<dealership name="Best in Town Cars">
<!-- This one should not get filtered out, because it is the only one
in this dealers list -->
<car>
<make>Chevy</make>
<model>Malibu</model>
<year>1979</year>
</car>
<car>
<make>Chevy</make>
<model>Caprice</model>
<year>1997</year>
</car>
<car>
<make>Buick</make>
<model>Skylark</model>
<year>1984</year>
</car>
</dealership>
<dealership name="Worst in Town Cars">
<car>
<make>Chevy</make>
<model>Malibu</model>
<year>1979</year>
</car>
<!-- This one should get filtered out, because it is the same as the
previous car in this dealers list-->
<car>
<make>Chevy</make>
<model>Malibu</model>
<year>1979</year>
</car>
<car>
<make>Buick</make>
<model>Skylark</model>
<year>1984</year>
</car>
</dealership>
</carlist>
The stylesheet I am using is:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/TR/REC-html40">
<xsl:output method="html" version="4.0" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<table border="1" cellpadding="3">
<tr>
<th>Dealer</th>
<th>Make</th>
<th>Model</th>
<th>Year</th>
</tr>
<xsl:for-each select="carlist/dealership">
<xsl:for-each select="./car">
<xsl:choose>
<xsl:when test="position() = 1">
<tr>
<td><xsl:value-of select="../@name"/></td>
<td><xsl:value-of select="./make"/></td>
<td><xsl:value-of select="./model"/></td>
<td><xsl:value-of select="./year"/></td>
</tr>
</xsl:when>
<xsl:when test="./make != ./preceding-sibling::car/make or ./model
!= ./preceding-sibling::car/model or ./year !=
./preceding-sibling::car/year">
<tr>
<td></td>
<td><xsl:value-of select="./make"/></td>
<td><xsl:value-of select="./model"/></td>
<td><xsl:value-of select="./year"/></td>
</tr>
</xsl:when>
<xsl:otherwise />
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
This stylesheet results in a table that looks like this:
<table border="1" cellpadding="3"
xmlns="http://www.w3.org/TR/REC-html40">
<tr>
<th>Dealer</th>
<th>Make</th>
<th>Model</th>
<th>Year</th>
</tr>
<tr>
<td>Fred's Used Cars</td>
<td>Chevy</td>
<td>Malibu</td>
<td>1979</td>
</tr>
<tr>
<td />
<td>Dodge</td>
<td>Charger</td>
<td>1979</td>
</tr>
<tr>
<td />
<td>Chevy</td>
<td>Malibu</td>
<td>1979</td>
</tr>
<tr>
<td>Best in Town Cars</td>
<td>Chevy</td>
<td>Malibu</td>
<td>1979</td>
</tr>
<tr>
<td />
<td>Chevy</td>
<td>Caprice</td>
<td>1997</td>
</tr>
<tr>
<td />
<td>Buick</td>
<td>Skylark</td>
<td>1984</td>
</tr>
<tr>
<td>Worst in Town Cars</td>
<td>Chevy</td>
<td>Malibu</td>
<td>1979</td>
</tr>
<tr>
<td />
<td>Buick</td>
<td>Skylark</td>
<td>1984</td>
</tr>
</table>
So it correctly filters out the second 1979 Chevy Malibu for the third
dealership, but not from the first dealership.
I recognize that the comparison:
<xsl:when test="./make != ./preceding-sibling::car/make or ./model !=
./preceding-sibling::car/model or ./year !=
./preceding-sibling::car/year">
is actually comparing this instance of ./make to only the first
preceding-sibling::car/make rather than what I would like,
which is all preceding-sibling::car/make values, but I can't figure out
how to make it compare with all of the preceding-sibling car/make
values.
Any help in penetrating my ignorance is greatly appreciated.
Regards,
Tim
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list