In this the catalog.xml
file. I have two books who have the same inventory (i.e. 20). I want to write an XSL file that will display the highest number of copies of a book in a catalog. If there are two or more books of the same inventory then they have to be displayed.
<catalog>
<Book>
<sku>12345</sku>
<title>Beauty Secrets</title>
<condition>New</condition>
<current_inventory>20</current_inventory>
<price>99.99</price>
</Book>
<Book>
<sku>54321</sku>
<title>Picturescapes</title>
<current_inventory>20</current_inventory>
<condition>New</condition>
<price>50.00</price>
</Book>
<Book>
<sku>33333</sku>
<title>Tourist Perspectives</title>
<condition>New</condition>
<current_inventory>0</current_inventory>
<price>75.00</price>
</Book>
<Book>
<sku>10001</sku>
<title>Fire in the Sky</title>
<condition>Used</condition>
<current_inventory>0</current_inventory>
<price>10.00</price>
</Book>
</catalog>
Below is my catalog3.xsl
file which is able to display only one out of the two books:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:variable name="max"/>
<xsl:template match="/">
<html>
<body>
<h2>Titles of Books for which Most Copies are Available</h2>
<table border="2">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>No of Copies</th>
</tr>
<xsl:apply-templates/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="catalog">
<xsl:for-each select="Book">
<xsl:sort select="current_inventory" data-type="number" order="descending"/>
<tr>
<xsl:if test="position()= 1">
<p><xsl:value-of select="$max = "/></p>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="current_inventory"/></td>
</xsl:if>
</tr>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Could anybody correct me to achieve my goal of displaying all the copies having the same maximum inventory in the catalog. Thanks.
The maximum current_inventory
can be calculated in the following manner:
<xsl:variable name="max">
<xsl:for-each select="/catalog/Book/current_inventory">
<xsl:sort data-type="number" order="descending"/>
<xsl:if test="position()=1"><xsl:value-of select="."/></xsl:if>
</xsl:for-each>
</xsl:variable>
Adjusting the criteria for the xsl:if
to compare the current_inventory
of the current node in the for-each
to the $max
variable achieves the desired result.
You were evaluating position()=1
inside of the for-each
, which will only be true for the first item in the sorted collection.
I set it to look for current_inventory
that is equal to the $max
:
<xsl:if test="current_inventory = $max">
Applying these changes to your stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--Determine the maximum current_inventory -->
<xsl:variable name="max">
<xsl:for-each select="/catalog/Book/current_inventory">
<xsl:sort data-type="number" order="descending"/>
<xsl:if test="position()=1"><xsl:value-of select="."/></xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:template match="/">
<html>
<body>
<h2>Titles of Books for which Most Copies are Available</h2>
<table border="2">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>No of Copies</th>
</tr>
<xsl:apply-templates/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="catalog">
<xsl:for-each select="Book">
<xsl:sort select="current_inventory" data-type="number" order="descending"/>
<xsl:if test="current_inventory = $max">
<tr>
<td>
<xsl:value-of select="title"/>
</td>
<td>
<xsl:value-of select="current_inventory"/>
</td>
</tr>
</xsl:if>
</xsl:for-each>
</xsl:template>
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