I have a list with songs that produced from a music application and I want to project the reverse list in a website. For example I have the list:
Deep Zone Vs Balthazar - Dj Take Me Away (In The Mix) (12:24:45)
Tom Boxer Feat Antonia - Morena (12:27:43)
Alexandra Stan - Lemonade (12:30:16)
Flo Rida feat. Timbaland - Elevator (12:33:43)
The XML file that creates the list is:
<?xml version="1.0" encoding="utf-8"?>
<Event status="happened">
<Song title="Dj Take Me Away (In The Mix)">
<Artist name="Deep Zone Vs Balthazar" ID="335712"></Artist>
<Info StartTime="12:24:45" JazlerID="12619" PlayListerID="" />
</Song>
<Song title="Morena">
<Artist name="Tom Boxer Feat Antonia" ID="335910"></Artist>
<Info StartTime="12:27:43" JazlerID="13079" PlayListerID="" />
</Song>
<Song title="Lemonade">
<Artist name="Alexandra Stan" ID="335773"></Artist>
<Info StartTime="12:30:16" JazlerID="12693" PlayListerID="" />
</Song>
<Song title="Elevator">
<Artist name="Flo Rida feat. Timbaland" ID="335818"></Artist>
<Info StartTime="12:33:43" JazlerID="12837" PlayListerID="" />
</Song>
</Event>
And the XSL file is:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="Event">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="Artist">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="Song">
<html>
<body>
<ul>
<li style="margin-bottom: -10px; margin-left: -30px; list-style: circle;">
<xsl:for-each select="Artist">
<xsl:value-of select="@name"/>
</xsl:for-each>
-
<xsl:value-of select="@title"/>
<span>
(<xsl:for-each select="Info">
<xsl:value-of select="@StartTime"/>
</xsl:for-each>)
</span><br />
</li>
</ul>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
How can I reverse the list so I can have the last played song on top of the list and follow by the earlier songs played?
I'm new to this community and despite the research I've made in the site, I didn't find a solution for the problem below.
CodePudding user response:
See if this works for you:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/Event">
<html>
<body>
<ul>
<xsl:for-each select="Song">
<xsl:sort select="position()" data-type="number" order="descending"/>
<li>
<xsl:value-of select="Artist/@name"/>
<xsl:text> - </xsl:text>
<xsl:value-of select="@title"/>
<xsl:text> (</xsl:text>
<xsl:value-of select="Info/@StartTime"/>
<xsl:text>)</xsl:text>
</li>
</xsl:for-each>
</ul>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
CodePudding user response:
XSLT/XPath 3 (or even 2, don't remember) has a reverse
function so doing select="reverse(Artist)"
will suffice in that version.
Otherwise use e.g.
<xsl:for-each select="Artist">
<xsl:sort select="position()" order="descending"/>
...
</xsl:for-each>
Based on your and further comments your original code using for-each select="Artist"
doesn't seem to process and output a "list" of artists at all, so that way of course, if you process a single Artist
element, neither reverse
nor sorting in reverse position()
order will change anything.
I suppose higher up you process the Song
elements so use <xsl:for-each select="reverse(Song)">
or <xsl:apply-templates select="reverse(Song)"/>
in XSLT 3 or <xsl:for-each select="Song"><xsl:sort select="position()" order="descending"/>...</xsl:for-each>
or <xsl:apply-templates select="Song"><xsl:sort select="position()" order="descending"/></xsl:apply-templates>
in versions where reverse
is not supported.