0

今日、iTunes からのプレイリスト エクスポート (xml) をきれいに印刷したいときに、XSLT を学びました。XSLT が XML とどのように関連しているか、そしてそれがどれほど有用であるかをようやく理解しました。iTunes2Htmlからコードを 取得し、独自の目的に合わせてカスタマイズしました。曲の再生時間/継続時間である動的な列を作成しました (開始時間と終了時間を設定する人/DJ に役立ちます!)。表示の最後に欲しかったのは、すべての期間列の合計です。その方法がわかりません。これまでのところ、スタックオーバーフローとグーグルについて調査しました。私が見つけた結果は紛らわしいものでした。

動的/計算された列の合計を計算する方法を理解するのを手伝ってくれる人はいますか? 同様の質問を参照してください

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) です。これは、どちらも存在しない場合、期間は長さと同じであることを意味します。つまり、最初から最後まで再生されます! どの曲にもその性質があります。ただし、ノード (開始または停止) の 1 つでも定義されている場合、持続時間は曲の合計の長さとは異なる場合があります。

サンプル 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
<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 に答える
0

xpath 関数sumを使用し、合計するすべてのノードを式で選択します。例えば

<xsl:value-of select="sum(/my/node)"/>
于 2012-04-05T18:16:05.060 に答える