I'm transforming an xml document to an html table using xslt, and now what I want to do is to change the background color of the cell containing the lowest "price" value without sorting my list.
I'm new on this, so what I'm doing is following the W3C schools examples. The xml file looks like this:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Black angel</title>
<artist>Savage Rose</artist>
<country>EU</country>
<company>Mega</company>
<price>11.90</price>
<year>1995</year>
</cd>
<cd>
<title>For the good times</title>
<artist>Kenny Rogers</artist>
<country>UK</country>
<company>Mucik Master</company>
<price>8.70</price>
<year>1995</year>
</cd>
</catalog>
And what I want to obtain is something similar to this but without ordering the elements in the list by price. So I want to maintain the original order in the XML document.
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
<th>Price</th>
</tr>
<xsl:for-each select="catalog/cd">
<xsl:sort select="price" order="ascending" data-type="number"/>
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
<xsl:choose>
<xsl:when test="(position() = 1)">
<td bgcolor="#ff00ff">
<xsl:value-of select="price"/></td>
</xsl:when>
<xsl:otherwise>
<td><xsl:value-of select="price"/></td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Thanks in advance for your help.
EDIT: I think I have found a solution for my question:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
<th>Price</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
<xsl:choose>
<xsl:when test="price=/catalog/cd/price[not(. > ../../cd/price)][1]">
<td bgcolor="#ff00ff">
<xsl:value-of select="price"/></td>
</xsl:when>
<xsl:otherwise>
<td><xsl:value-of select="price"/></td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
And what I want to obtain is something similar to this but without ordering the elements in the list by price.
The fact that sorting is used for finding the minimum doesn't mean that any elements will be re-ordered. Finding the minimum using <xsl:sort>
is in practice the fastest way to do so in XSLT 1.0 -- and doesn't require any extension functions:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="vLowest">
<xsl:for-each select="/*/*/price">
<xsl:sort data-type="number"/>
<xsl:if test="position()=1"><xsl:value-of select="."/></xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:template match="/*">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
<th>Price</th>
</tr>
<xsl:apply-templates select="cd"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="cd">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
<td>
<xsl:if test="price=number($vLowest)">
<xsl:attribute name="bgcolor">#ff00ff</xsl:attribute>
</xsl:if>
<xsl:value-of select="price"/>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document:
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Black angel</title>
<artist>Savage Rose</artist>
<country>EU</country>
<company>Mega</company>
<price>11.90</price>
<year>1995</year>
</cd>
<cd>
<title>For the good times</title>
<artist>Kenny Rogers</artist>
<country>UK</country>
<company>Mucik Master</company>
<price>8.70</price>
<year>1995</year>
</cd>
</catalog>
the wanted, correct result is produced:
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
<th>Price</th>
</tr>
<tr>
<td>Empire Burlesque</td>
<td>Bob Dylan</td>
<td>10.90</td>
</tr>
<tr>
<td>Black angel</td>
<td>Savage Rose</td>
<td>11.90</td>
</tr>
<tr>
<td>For the good times</td>
<td>Kenny Rogers</td>
<td bgcolor="#ff00ff">8.70</td>
</tr>
</table>
</body>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With