Reputation: 1813
I'be got a rather large XML file that contains a list of vehicle models, their price and a monthly payment price. There is actually loads of other information in there, but those are the salient bits of data I'm interested in.
There are loads of duplicate models in there at different prices/monthly payments. My task, which I have done so far with the help of this forum, is to construct a distinct list of the models (IE. no duplicates), showing the lowest priced vehicle in that model.
The bit I'm stuck on, is I then need to sort this list displaying the lowest monthly payment to the highest monthly payment. The complication being the lowest priced vehicle don't always equal the lowest monthly payment.
My XML looks a bit like this:
<?xml version="1.0" encoding="utf-8"?>
<Dealer>
<Vehicle>
<Model>KA</Model>
<DealerPriceNoFormat>8700.00</DealerPriceNoFormat>
<OptionsFinanceMonthlyPayment>300.50</OptionsFinanceMonthlyPayment>
</Vehicle>
<Vehicle>
<Model>KA</Model>
<DealerPriceNoFormat>10000.50</DealerPriceNoFormat>
<OptionsFinanceMonthlyPayment>270.50</OptionsFinanceMonthlyPayment>
</Vehicle>
<Vehicle>
<Model>Focus</Model>
<DealerPriceNoFormat>12000.00</DealerPriceNoFormat>
<OptionsFinanceMonthlyPayment>340.00</OptionsFinanceMonthlyPayment>
</Vehicle>
<Vehicle>
<Model>KA</Model>
<DealerPriceNoFormat>9910.00</DealerPriceNoFormat>
<OptionsFinanceMonthlyPayment>430.75</OptionsFinanceMonthlyPayment>
</Vehicle>
<Vehicle>
<Model>KUGA</Model>
<DealerPriceNoFormat>23010.00</DealerPriceNoFormat>
<OptionsFinanceMonthlyPayment>550.20</OptionsFinanceMonthlyPayment>
</Vehicle>
<Vehicle>
<Model>Focus</Model>
<DealerPriceNoFormat>15900.00</DealerPriceNoFormat>
<OptionsFinanceMonthlyPayment>430.00</OptionsFinanceMonthlyPayment>
</Vehicle>
</Dealer>
As I said, there is loads of other data in there, but that's the basic structure.
And my XSLT looks like this:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="html" omit-xml-declaration="yes" indent="yes" version="4.0" encoding="iso-8859-1" />
<xsl:key name="by-id" match="Dealer/Vehicle" use="Model"/>
<xsl:template match="Dealer">
<xsl:copy>
<xsl:for-each select="Vehicle[generate-id() = generate-id(key('by-id', Model)[1])]">
<xsl:for-each select="key('by-id', Model)">
<xsl:sort select="DealerPriceNoFormat" data-type="number" order="ascending" />
<xsl:if test="position()=1">
<p>
<xsl:value-of select="Model" /><br />
<xsl:value-of select="DealerPriceNoFormat" /><br />
<xsl:value-of select="OptionsFinanceMonthlyPayment" />
</p>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Like I say, I'm almost there, just can't figure out how to then sort the output list by OptionsFinanceMonthlyPayment.
So the in the case above output would look something like this, showing the cheapest car in each model, but sorted by the monthly payment on the output list:
KA
8700.00
300.50
Focus
12000.00
340.00
KUGA
23010.00
550.20
Thanks in advance.
Upvotes: 0
Views: 128
Reputation: 117140
I would do this in two passes - something like:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:key name="vehicle-by-model" match="Vehicle" use="Model"/>
<xsl:template match="/Dealer">
<!-- first-pass -->
<xsl:variable name="groups">
<xsl:for-each select="Vehicle[generate-id() = generate-id(key('vehicle-by-model', Model)[1])]">
<group>
<xsl:for-each select="key('vehicle-by-model', Model)">
<xsl:sort select="DealerPriceNoFormat" data-type="number" order="ascending" />
<xsl:if test="position()=1">
<model><xsl:value-of select="Model" /></model>
<price><xsl:value-of select="DealerPriceNoFormat" /></price>
<pmt><xsl:value-of select="OptionsFinanceMonthlyPayment" /></pmt>
</xsl:if>
</xsl:for-each>
</group>
</xsl:for-each>
</xsl:variable>
<!-- output -->
<html>
<xsl:for-each select="exsl:node-set($groups)/group">
<xsl:sort select="pmt" data-type="number" order="ascending" />
<p>
<xsl:value-of select="model" /><br />
<xsl:value-of select="price" /><br />
<xsl:value-of select="pmt" />
</p>
</xsl:for-each>
</html>
</xsl:template>
</xsl:stylesheet>
Note that this requires a processor that supports a node-set()
extension function.
Upvotes: 2