我刚刚学习了XSLT,当时我想从itunes打印播放列表导出(xml)。我终于明白了XSLT如何与XML相关以及它有多么有用。我从中获取了代码 iTunes2Html并根据自己的目的进行定制。我创建了一个动态列,它是一首歌的播放时间/持续时间(对设置开始和结束时间的人/ dj很有用!)。在显示结束时我想要的是所有持续时间列的总和。我无法弄清楚如何做到这一点。到目前为止,我已经研究过堆栈溢出和谷歌没有运气。我发现的结果令人困惑。
那么有人可以帮我弄清楚如何计算动态/计算列的总和吗?见similar question
以下是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>
编辑:澄清持续时间计算的逻辑。由于启动和停止是可选的,实际公式是(停止|总) - (开始| 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))
答案 0 :(得分:1)
这应该可以准确地为您提供所需内容:
<xsl:variable name="total" select="
sum(song[Stop_Time > 0]/Stop_Time | song[not(Stop_Time > 0)]/Total_Time)
-
sum(song/Start_Time)
" />
对于您的XML示例,评估结果为583274
,即9m, 43s
。
答案 1 :(得分:0)
使用xpath函数sum并使用表达式选择要求的所有节点。 例如
<xsl:value-of select="sum(/my/node)"/>
答案 2 :(得分: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。我把它放在这里供将来参考。