Grouping Songs By Artist - Exercise

Contact Us or call 1-877-932-8228
Grouping Songs By Artist - Exercise

Grouping Songs By Artist

Duration: 20 to 30 minutes.

In this exercise, you will practice grouping with keys and the generate-id() function.

  1. Open Keys/Exercises/Top500SongsGrouped.xml and review the code. You will see that it contains a list of Song elements. We've seen this document before.
  2. Open Keys/Exercises/GroupSongs.xsl for editing.
  3. Write code that outputs the songs by artist. For each artist, the output should appear something like this:
    <h2>34. Animals - 4 Song(s)</h2>
    <ol>
    	<li>House Of The Rising Sun</li>
    	<li>We Gotta Get Out Of This Place</li>
    	<li>Don't Let Me Be Misunderstood</li>
    	<li>It's My Life</li>
    </ol>
    where 34 is the position of the artist (i.e., there are 33 artists that appear before the Animals, Animals is the name of the artist, and 4 is the number of songs the artist has in the top 500.
  4. To test your solution, transform Keys/Exercises/Top500SongsGrouped.xml against Keys/Exercises/GroupSongs.xsl.

Code Sample:

Keys/Exercises/GroupSongs.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
				xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="xml" indent="yes"/>
	<xsl:key name="keySong" match="Song" use="@Artist"/>
	
	<xsl:template match="/">
		<html>
			<head>
				<title>Hits By Artist</title>
			</head>
			<body>
				<!--
					Write code that outputs the songs by artist.
					Challenge: Sort the results so that the artist with the most 
						songs appears first.
				-->
			</body>
		</html>
	</xsl:template>
	
</xsl:stylesheet>

Challenge

Sort the results so that the artist with the most songs appears first.

Solution:

Keys/Solutions/GroupSongs.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
				xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="xml" indent="yes"/>
	<xsl:key name="keySong" match="Song" use="@Artist"/>
	
	<xsl:template match="/">
		<html>
			<head>
				<title>Hits By Artist</title>
			</head>
			<body>
			<xsl:for-each 
				select="Songs/Song[generate-id(.)=generate-id(key('keySong',@Artist))]">
				<h2>
					<xsl:value-of select="position()"/>.  
					<xsl:value-of select="@Artist"/> -
					<xsl:value-of select="count(key('keySong',@Artist))"/> Song(s)
				</h2>
				<ol>
					<xsl:for-each select="key('keySong',@Artist)">
						<li><xsl:value-of select="."/></li>
					</xsl:for-each>
				</ol>
			</xsl:for-each>
			</body>
		</html>
	</xsl:template>
	
</xsl:stylesheet>

Challenge Solution:

Keys/Solutions/GroupSongs-challenge.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
				xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="xml" indent="yes"/>
	<xsl:key name="keySong" match="Song" use="@Artist"/>
	
	<xsl:template match="/">
		<html>
			<head>
				<title>Hits By Artist</title>
			</head>
			<body>
			<xsl:for-each 
				select="Songs/Song[generate-id(.)=generate-id(key('keySong',@Artist))]">
				<xsl:sort select="count(key('keySong',@Artist))" 
					order="descending" data-type="number"/>
				<h2>
					<xsl:value-of select="position()"/>.  
					<xsl:value-of select="@Artist"/> -
					<xsl:value-of select="count(key('keySong',@Artist))"/> Song(s)
				</h2>
				<ol>
					<xsl:for-each select="key('keySong',@Artist)">
						<li><xsl:value-of select="."/></li>
					</xsl:for-each>
				</ol>
			</xsl:for-each>
			</body>
		</html>
	</xsl:template>
	
</xsl:stylesheet>
Next