Обратный список XSL

#xml #xslt

Вопрос:

У меня есть список песен, созданных из музыкального приложения, и я хочу спроецировать обратный список на веб-сайт. Например, у меня есть список:

 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)  

XML-файл, который создает список, является:

 lt;?xml version="1.0" encoding="utf-8"?gt; lt;Event status="happened"gt;  lt;Song title="Dj Take Me Away (In The Mix)"gt;  lt;Artist name="Deep Zone Vs Balthazar" ID="335712"gt;lt;/Artistgt;  lt;Info StartTime="12:24:45" JazlerID="12619" PlayListerID="" /gt;  lt;/Songgt;  lt;Song title="Morena"gt;  lt;Artist name="Tom Boxer Feat Antonia" ID="335910"gt;lt;/Artistgt;  lt;Info StartTime="12:27:43" JazlerID="13079" PlayListerID="" /gt;  lt;/Songgt;  lt;Song title="Lemonade"gt;  lt;Artist name="Alexandra Stan" ID="335773"gt;lt;/Artistgt;  lt;Info StartTime="12:30:16" JazlerID="12693" PlayListerID="" /gt;  lt;/Songgt;  lt;Song title="Elevator"gt;  lt;Artist name="Flo Rida feat. Timbaland" ID="335818"gt;lt;/Artistgt;  lt;Info StartTime="12:33:43" JazlerID="12837" PlayListerID="" /gt;  lt;/Songgt; lt;/Eventgt;  

И файл XSL является:

 lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"gt;   lt;xsl:template match="Event"gt; lt;xsl:apply-templates/gt; lt;/xsl:templategt;  lt;xsl:template match="Artist"gt; lt;xsl:apply-templates/gt; lt;/xsl:templategt;  lt;xsl:template match="Song"gt;   lt;htmlgt; lt;bodygt;  lt;ulgt;  lt;li style="margin-bottom: -10px; margin-left: -30px; list-style: circle;"gt;  lt;xsl:for-each select="Artist"gt;  lt;xsl:value-of select="@name"/gt;  lt;/xsl:for-eachgt;  -   lt;xsl:value-of select="@title"/gt;   lt;spangt;  (lt;xsl:for-each select="Info"gt;  lt;xsl:value-of select="@StartTime"/gt;  lt;/xsl:for-eachgt;)  lt;/spangt;lt;br /gt;  lt;/ligt;  lt;/ulgt;  lt;/bodygt; lt;/htmlgt;  lt;/xsl:templategt;  lt;/xsl:stylesheetgt;  

Как я могу изменить список, чтобы последняя сыгранная песня была в верхней части списка и за ней следовали более ранние сыгранные песни?


Я новичок в этом сообществе, и, несмотря на исследования, которые я провел на сайте, я не нашел решения проблемы, описанной ниже.

Ответ №1:

Посмотрим, сработает ли это для вас:

XSLT 1.0

 lt;xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"gt; lt;xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/gt;  lt;xsl:template match="/Event"gt;  lt;htmlgt;  lt;bodygt;  lt;ulgt;  lt;xsl:for-each select="Song"gt;  lt;xsl:sort select="position()" data-type="number" order="descending"/gt;  lt;ligt;  lt;xsl:value-of select="Artist/@name"/gt;  lt;xsl:textgt; - lt;/xsl:textgt;  lt;xsl:value-of select="@title"/gt;  lt;xsl:textgt; (lt;/xsl:textgt;  lt;xsl:value-of select="Info/@StartTime"/gt;  lt;xsl:textgt;)lt;/xsl:textgt;  lt;/ligt;  lt;/xsl:for-eachgt;   lt;/ulgt;  lt;/bodygt;  lt;/htmlgt; lt;/xsl:templategt;  lt;/xsl:stylesheetgt;  

Ответ №2:

В XSLT/XPath 3 (или даже 2, не помню) есть reverse функция, поэтому select="reverse(Artist)" в этой версии этого будет достаточно.

В противном случае используйте, например

 lt;xsl:for-each select="Artist"gt;  lt;xsl:sort select="position()" order="descending"/gt;  ... lt;/xsl:for-eachgt;  

Основываясь на ваших и дальнейших комментариях, ваш исходный код for-each select="Artist" , похоже, вообще не обрабатывает и не выводит «список» исполнителей, так что, конечно, если вы обработаете один Artist элемент, ни reverse сортировка, ни сортировка в обратном position() порядке ничего не изменят.

Я полагаю, что выше вы обрабатываете Song элементы, поэтому используйте lt;xsl:for-each select="reverse(Song)"gt; или lt;xsl:apply-templates select="reverse(Song)"/gt; в XSLT 3 lt;xsl:for-each select="Song"gt;lt;xsl:sort select="position()" order="descending"/gt;...lt;/xsl:for-eachgt; , или lt;xsl:apply-templates select="Song"gt;lt;xsl:sort select="position()" order="descending"/gt;lt;/xsl:apply-templatesgt; в версиях, где reverse это не поддерживается.

Комментарии:

1. Большое спасибо за ваш ответ. Моя версия xsl, к сожалению, 1.0, и она взята из версии музыкального приложения. Я не могу его обновить. Есть ли какое-либо решение для этой версии?

2. @DigiSol, ответ дает альтернативу, нет? Если for-each select="Artist" в вашем исходном коде все работает и выводится в порядке документа, просто добавьте lt;xsl:sort select="position()" order="descending"/gt; в вывод в обратном порядке.

3. Так и должно быть lt;xsl:for-each select="Song"gt; . С данной структурой lt;xsl:for-each select="Artist"gt; никогда не будет возвращать список из любого контекста.

4. @Мартин Хоннен, это не работает с обоими решениями

5. @michael.hor257k: это не работает с обоими решениями