0

我今天刚学习 XSLT,当时我想从 iTunes 中漂亮地打印播放列表导出 (xml)。我终于明白了 XSLT 与 XML 的关系以及它的用途。我从 iTunes2Html中获取了代码,并为我自己的目的对其进行了定制。我创建了一个动态列,它是歌曲的播放时间/持续时间(对于设置开始和结束时间的人/djs 很有用!)。在显示结束时我想要的是所有持续时间列的总和。我不知道该怎么做。到目前为止,我已经研究了堆栈溢出和谷歌,但没有运气。我发现的结果令人困惑。

那么任何人都可以帮我弄清楚如何计算动态/计算列的总数吗?看到类似的问题

这是 XSLT 的相关部分

<td> <!-- calculating duration : formattime(end | total - start | 0), is there a simpler way to do it? -->
<xsl:variable name="totduration">
 <xsl:choose>
    <xsl:when test="string(number(following-sibling::Start_Time))='NaN'">
        <xsl:value-of select="following-sibling::Stop_Time"/>
    </xsl:when>
    <xsl:when test="string(number(following-sibling::Stop_Time))='NaN'">
        <xsl:value-of  select="number(following-sibling::Total_Time) - number(following-sibling::Start_Time)"/>
    </xsl:when>          
    <xsl:otherwise>
        <xsl:value-of  select="number(following-sibling::Stop_Time) - number(following-sibling::Start_Time)"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:variable>
<!-- for the javascript approach using jquery. didn't work -->
<span class="sumData" style="display:none"> <xsl:value-of select="$totduration"/></span> 
<xsl:call-template name="formatTime">
  <xsl:with-param name="t" select="$totduration"/>
</xsl:call-template>
</td>

编辑:澄清持续时间计算的逻辑。由于 start 和 stop 是可选的,因此实际公式为 (stop | total) - (start | 0)。这意味着如果两者都不存在,则持续时间与长度相同,即它从头到尾播放!每首歌都有这个属性。但是,即使定义了一个节点(开始或停止),则持续时间可能与歌曲的总长度不同。

一些示例 XML

  <songlist>
<song>
  <Track_ID>169</Track_ID>
  <Name>AAAAA</Name>
  <Album>AAAAA</Album>
  <Genre>AAAAA</Genre>
  <Start_Time>78000</Start_Time>
  <Stop_Time>122000</Stop_Time>
  <Total_Time>357537</Total_Time>
</song>
<song>
  <Track_ID>174</Track_ID>
  <Name>BBBBBB</Name>
  <Artist>BBBBBB</Artist>
  <Album>BBBBBB</Album>
  <Genre>BBBBBB</Genre>
  <Stop_Time>120000</Stop_Time>
  <Total_Time>275043</Total_Time>
</song>
<song>
  <Track_ID>177</Track_ID>
  <Name>CCCCCC</Name>
  <Artist>CCCCCC</Artist>
  <Album>CCCCCC</Album>
  <Genre>CCCCCC</Genre>
  <Stop_Time>62000</Stop_Time>
  <Total_Time>287738</Total_Time>
</song>
<song>
  <Track_ID>180</Track_ID>
  <Name>DDDDDDD</Name>
  <Artist>DDDDDDD</Artist>
  <Album>DDDDDDD</Album>
  <Genre>DDDDDDD</Genre>
  <Start_Time>43000</Start_Time>
  <Total_Time>400274</Total_Time>
</song>

这是输出 截屏

将出现在持续时间列底部的所需输出(即所有持续时间的总和):

Total Playtime Duration - 9:43

还有更好的方法(如上所示)在 xslt 中执行此公式吗?我目前正在使用xsl:choose检查 NaN 并相应地使用替代方法。我不禁认为必须有更好的方法。

formattime((stop | total) - (start | 0))
4

3 回答 3

1

这应该会给你你正在寻找的东西:

<xsl:variable name="total" select="
  sum(song[Stop_Time &gt; 0]/Stop_Time | song[not(Stop_Time &gt; 0)]/Total_Time)
  -
  sum(song/Start_Time)
" />

对于您的 XML 示例,它的计算结果为583274,即9m, 43s

于 2012-04-07T11:06:53.320 回答
0

使用 xpath 函数sum并使用表达式选择要求和的所有节点。例如

<xsl:value-of select="sum(/my/node)"/>
于 2012-04-05T18:16:05.060 回答
0
<xsl:variable name="totalduration" select="
  sum($songs/song[Stop_Time > 0]/Stop_Time | $songs/song[not(Stop_Time > 0)]/Total_Time )
  -
  sum($songs/song/Start_Time)
" />
<p> Total Duration for playlist:   
  <xsl:call-template name="formatTime">
    <xsl:with-param name="t" select="$totalduration"/>
  </xsl:call-template>
</p>

感谢@tomalak,这是我最终使用的最终代码。我把它放在这里以供将来参考。

于 2012-04-10T03:16:34.507 回答