【问题标题】:XSL list ReverseXSL 列表反向
【发布时间】:2025-12-26 02:15:10
【问题描述】:

我有一个音乐应用程序制作的歌曲列表,我想将反向列表投影到网站中。例如我有一个列表:

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 文件是:

<?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>

XSL 文件是:

<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>

如何反转列表,以便将最后播放的歌曲放在列表顶部,然后播放较早的歌曲?


我是这个社区的新手,尽管我在网站上进行了研究,但我没有找到以下问题的解决方案。

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    看看这是否适合你:

    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>
    

    【讨论】:

      【解决方案2】:

      XSLT/XPath 3(甚至是 2,不记得了)有一个 reverse 函数,所以在那个版本中使用 select="reverse(Artist)" 就足够了。

      否则使用例如

      <xsl:for-each select="Artist">
        <xsl:sort select="position()" order="descending"/>
        ...
      </xsl:for-each>
      

      根据您的和进一步的 cmets,您使用 for-each select="Artist" 的原始代码似乎根本不会处理和输出艺术家的“列表”,所以当然,如果您处理单个 Artist 元素,也不会reverse 或反向排序 position() 顺序不会改变任何事情。

      我想你在更高层处理 Song 元素,所以在不支持 reverse 的版本中使用 XSLT 3 中的 &lt;xsl:for-each select="reverse(Song)"&gt;&lt;xsl:apply-templates select="reverse(Song)"/&gt;&lt;xsl:for-each select="Song"&gt;&lt;xsl:sort select="position()" order="descending"/&gt;...&lt;/xsl:for-each&gt;&lt;xsl:apply-templates select="Song"&gt;&lt;xsl:sort select="position()" order="descending"/&gt;&lt;/xsl:apply-templates&gt;

      【讨论】:

      • 非常感谢您的回复。不幸的是,我的 xsl 版本是 1.0,来自音乐应用程序的版本。我无法升级它。这个版本有解决方案吗?
      • @DigiSol,答案给出了另一种选择,不是吗?如果您原始代码中的for-each select="Artist" 可以正常工作并按文档顺序输出内容,则只需将&lt;xsl:sort select="position()" order="descending"/&gt; 添加到以相反顺序输出即可。
      • 应该是&lt;xsl:for-each select="Song"&gt;。使用给定的结构,&lt;xsl:for-each select="Artist"&gt; 将永远不会从任何上下文返回列表。
      • @Martin Honnen,这两种解决方案都不适用
      • @michael.hor257k:这两种解决方案都不适用