Reputation: 45
How do I use the element to sort the elements within the table I am outputting? I would like to use the elements within the element. I tried placing the element in my xsl document but it doesn't sort the element.
Here is my xml:
<presidents xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="president.xsd" date="2014-09-24" >
<president>
<number>1</number>
<name>George Washington</name>
<birthday>1732-02-22</birthday>
<took_office>1789-04-30</took_office>
<left_office>1797-03-04</left_office>
<party>no party</party>
<term>
<term_number>1</term_number>
<vice_president>John Adams</vice_president>
</term>
<term>
<term_number>2</term_number>
<vice_president>John Adams</vice_president>
</term>
</president>
<president>
<number>2</number>
<name>John Adams</name>
<birthday>1735-10-30</birthday>
<took_office>1797-03-04</took_office>
<left_office>1801-03-04</left_office>
<party>Federalist</party>
<term>
<term_number>3</term_number>
<vice_president>Thomas Jefferson</vice_president>
</term>
</president>
</presidents>
And here is my .xsl:
<xsl:template match="/">
<html>
<head>
<link rel="stylesheet" type="text/css" href="president_table.css"/>
<title>Table of Us Presidents</title>
</head>
<body>
<h1>Table of Us Presidents</h1>
<table>
<tr>
<th>Name</th>
<th>Birthday</th>
<th>Took Office</th>
<th>Left Office</th>
<th>Party</th>
<th>Vice President</th>
</tr>
<xsl:apply-templates/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="president">
<tr>
<td><xsl:apply-templates select="name"/></td>
<td><xsl:apply-templates select="birthday"/></td>
<td><xsl:apply-templates select="took_office"/></td>
<td><xsl:apply-templates select="left_office"/></td>
<td>
<xsl:apply-templates select="party">
<xsl:sort select="party"/>
</xsl:apply-templates>
</td>
<td>
<xsl:for-each select="term">
<xsl:number value="position()" format="1. " />
<xsl:value-of select="vice_president" /><br />
</xsl:for-each>
</td>
</tr>
</xsl:template>
Upvotes: 4
Views: 3343
Reputation: 22617
I would like to output the data so it is sorted according to the element in an alphabetical order. So all of the 'Democratic' presidents would appear first.
Then, let us test with an example where the natural order of elements would not suggest that a Democratic president comes first in the output:
XML Input
<presidents date="2014-09-24" >
<president>
<number>1</number>
<name>George Washington</name>
<birthday>1732-02-22</birthday>
<took_office>1789-04-30</took_office>
<left_office>1797-03-04</left_office>
<party>Federalist</party>
<term>
<term_number>1</term_number>
<vice_president>John Adams</vice_president>
</term>
<term>
<term_number>2</term_number>
<vice_president>John Adams</vice_president>
</term>
</president>
<president>
<number>2</number>
<name>John Adams</name>
<birthday>1735-10-30</birthday>
<took_office>1797-03-04</took_office>
<left_office>1801-03-04</left_office>
<party>Democratic</party>
<term>
<term_number>3</term_number>
<vice_president>Thomas Jefferson</vice_president>
</term>
</president>
</presidents>
Then, on to sorting your data. Currently, you are applying xsl:sort
in the context of a template matching president
, like this:
<xsl:apply-templates select="party">
<xsl:sort select="party"/>
</xsl:apply-templates>
But the unit you'd like to sort is not party
, but president
elements. It just that the sort condition is the textual content of the party
element, which is a child element of president
.
So, you have to apply sorting higher up in the XML hierarchy for the desired effect. You have to sort in the context of presidents
, where templates are applied to president
elements.
Stylesheet
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" doctype-public="XSLT-compat" indent="yes" />
<xsl:template match="/presidents">
<html>
<head>
<link rel="stylesheet" type="text/css" href="president_table.css"/>
<title>Table of Us Presidents</title>
</head>
<body>
<h1>Table of Us Presidents</h1>
<table>
<tr>
<th>Name</th>
<th>Birthday</th>
<th>Took Office</th>
<th>Left Office</th>
<th>Party</th>
<th>Vice President</th>
</tr>
<xsl:apply-templates select="president">
<xsl:sort select="party"/>
</xsl:apply-templates>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="president">
<tr>
<td><xsl:apply-templates select="name"/></td>
<td><xsl:apply-templates select="birthday"/></td>
<td><xsl:apply-templates select="took_office"/></td>
<td><xsl:apply-templates select="left_office"/></td>
<td>
<xsl:apply-templates select="party"/>
</td>
<td>
<xsl:for-each select="term">
<xsl:number value="position()" format="1. " />
<xsl:value-of select="vice_president" /><br />
</xsl:for-each>
</td>
</tr>
</xsl:template>
</xsl:transform>
HTML Output
As you can see, the president with the Democratic party now comes first.
<!DOCTYPE html
PUBLIC "XSLT-compat">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="president_table.css">
<title>Table of Us Presidents</title>
</head>
<body>
<h1>Table of Us Presidents</h1>
<table>
<tr>
<th>Name</th>
<th>Birthday</th>
<th>Took Office</th>
<th>Left Office</th>
<th>Party</th>
<th>Vice President</th>
</tr>
<tr>
<td>John Adams</td>
<td>1735-10-30</td>
<td>1797-03-04</td>
<td>1801-03-04</td>
<td>Democratic</td>
<td>1. Thomas Jefferson<br></td>
</tr>
<tr>
<td>George Washington</td>
<td>1732-02-22</td>
<td>1789-04-30</td>
<td>1797-03-04</td>
<td>Federalist</td>
<td>1. John Adams<br>2. John Adams<br></td>
</tr>
</table>
</body>
</html>
Upvotes: 3