#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: это не работает с обоими решениями