[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Determining uniqueness based on mulitple element value

Subject: Determining uniqueness based on mulitple element values
From: Tim Lewis <lewist@xxxxxxxxxxx>
Date: Fri, 13 Dec 2002 14:33:49 -0500
malibu 1979
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


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.