Reputation: 295
I have an XML file that contains price value.I want to sort my table in order of price: here is my code but in IE it doesn't work and the value of other elements together show in price tabledata:
<td>
<xsl:apply-templates >
<xsl:sort select="price" data-type="number" order="descending" />
</xsl:apply-templates>
</td>
and my xml file (book.xml)
this is my XSLT file:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="catalog">
<html>
<head>
<title>
<xsl:text>Buchhandlung</xsl:text>
</title>
</head>
<table border="1">
<tr>
<th>id</th>
<th>author</th>
<th>titel</th>
<th>price</th>
<th>description</th>
</tr>
<xsl:apply-templates />
</table>
</html>
</xsl:template>
<xsl:template match="book">
<tr>
<td>
<xsl:apply-templates select="@id" />
</td>
<td>
<xsl:apply-templates select="author" />
</td>
<td>
<xsl:apply-templates select="title" />
</td>
<td>
<xsl:apply-templates select="book" >
<xsl:sort select="price" data-type="number" order="descending" />
</xsl:apply-templates>
</td>
<!--<td>
<xsl:apply-templates select="price" />
</td>-->
<td>
<xsl:apply-templates select="description" />
</td>
</tr>
</xsl:template>
<
/xsl:stylesheet>
Thank you for your helps
Upvotes: 1
Views: 2396
Reputation: 5403
sort
by itself doesn't produce output. It dictates the order in which the sorted node-set is passed to anything in the current scope - so you'll need to add something like <xsl:value-of select="price"/>
below it - the value-of instruction will print out the prices in order of size instead of the natural order of the file.
edit #1: I've now noticed you're using it inside apply-templates
and not for-each
. In this case, you'll need to define a template that matches a price
node. This template will then be called on each price node in your sort order, instead of their order in the file.
edit #2: An example; to print a list of book details in order of the price of the book, you'll probably want something like:
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="catalog">
<html>
<head>
<title>
<xsl:text>Buchhandlung</xsl:text>
</title>
</head>
<table border="1">
<tr>
<th>id</th>
<th>author</th>
<th>titel</th>
<th>price</th>
<th>description</th>
</tr>
<xsl:apply-templates select="book">
<xsl:sort select="price"/>
</xsl:apply-templates>
</table>
</html>
</xsl:template>
<xsl:template match="book">
<tr>
<td>
<xsl:apply-templates select="@id" />
</td>
<td>
<xsl:apply-templates select="author" />
</td>
<td>
<xsl:apply-templates select="title" />
</td>
<td>
<xsl:apply-templates select="description" />
</td>
</tr>
</xsl:template>
Notice that the catalog template now contains the sorting logic, and I have removed similar logic from the book template. The book template has no power to sort the nodes passed into it, you have to dictate what order the target nodes are passed to the book template to get the result you're after. The catalog template ensures that each book
element is passed into template match="book"
in order of price, not the order in the file. I've assumed that you don't want to print the book price inside the book details since the example you gave wouldn't have done this either, but if you want to include this information it would be done in exactly the same way as the td
output for the other fields.
Upvotes: 3
Reputation: 167446
You need code along the lines of
<xsl:template match="catalog">
<table>
<tbody>
<xsl:apply-templates select="book">
<xsl:sort select="price" data-type="number" order="descending"/>
</xsl:appl-templates>
</tbody>
</table>
</xsl:template>
<xsl:template match="book">
<tr>
<xsl:apply-templates/>
</tr>
</xsl:template>
<xsl:template match="book/*">
<td>
<xsl:value-of select="."/>
</td>
</xsl:template>
Upvotes: 1