在iTunes中,当您以XML格式导出播放列表时,它会自动按照“添加日期”而不是用户订购的顺序对其进行排序。接近XML文件的末尾,它列出了用户通过歌曲ID对其进行排序的播放列表的顺序,如下所示:
<key>Playlist Items</key>
<array>
<dict>
<key>Track ID</key><integer>5365</integer>
</dict>
<dict>
<key>Track ID</key><integer>5317</integer>
</dict>
<dict>
<key>Track ID</key><integer>5235</integer>
</dict>
<array>
我使用这个XSL转换了XML文档:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<table>
<tr>
<th>Name</th>
<th>Artist</th>
<th>Year</th>
</tr>
<xsl:call-template name="records" />
</table>
</xsl:template>
<xsl:template name="records">
<xsl:for-each select="/*/*/dict[1]/dict">
<xsl:element name="tr">
<xsl:call-template name="songs" />
</xsl:element>
</xsl:for-each>
</xsl:template>
<xsl:template name="songs">
<td>
<xsl:value-of select="child::*[preceding-sibling::* = 'Track ID']" />
</td>
<td>
<xsl:value-of select="child::*[preceding-sibling::* = 'Name']" />
</td>
<td>
<xsl:value-of select="child::*[preceding-sibling::* = 'Artist']" />
</td>
</xsl:template>
</xsl:stylesheet>
我想知道如何根据原始XML文件末尾出现的用户指定顺序而不是“添加日期”来编辑我的XSL以转换我的播放列表以重新排序所有内容?
编辑 - 添加更多原始XML。以下是与我所做的XSL有关的片段:
<key>5189</key>
<dict>
<key>Track ID</key><integer>5189</integer>
<key>Name</key><string>varsity jacket</string>
<key>Artist</key><string>bayou</string>
<key>Kind</key><string>MPEG audio file</string>
<key>Size</key><integer>3532008</integer>
<key>Total Time</key><integer>220107</integer>
<key>Date Modified</key><date>2015-07-26T14:04:34Z</date>
<key>Date Added</key><date>2015-07-26T14:04:17Z</date>
<key>Bit Rate</key><integer>128</integer>
<key>Sample Rate</key><integer>44100</integer>
<key>Play Count</key><integer>1</integer>
<key>Play Date</key><integer>3520959994</integer>
<key>Play Date UTC</key><date>2015-07-29T00:26:34Z</date>
<key>Skip Count</key><integer>2</integer>
<key>Skip Date</key><date>2015-08-29T05:12:33Z</date>
<key>Persistent ID</key><string>BE57D36AF01737E3</string>
<key>Track Type</key><string>File</string>
<key>Location</key><string>file:///Users/jason/Music/iTunes/iTunes%20Music/bayou/Unknown%20Album/varsity%20jacket.mp3</string>
<key>File Folder Count</key><integer>4</integer>
<key>Library Folder Count</key><integer>1</integer>
</dict>
答案 0 :(得分:0)
对您的代码提出必要但友好的建议:如果您对xsl:call-template
满意,请不要将xsl:apply-templates
与上下文一起使用,因为它会限制您的流量并使代码复杂化。
查看我的编辑。我采用了您的结构,但通过删除xsl:call-template
进行了简化,但没有任何其他目的。
要排序,只需使用xsl:sort
作为xsl:apply-templates
的孩子。在这里,我按照艺术家的名字排序。如果需要,可以通过添加更多xsl:sort
元素来添加更多排序键。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- from SO: http://stackoverflow.com/questions/32432619/how-to-sort-xml-in-given-order-messing-with-exported-itunes-playlists -->
<xsl:output indent="yes" />
<xsl:template match="/">
<table>
<tr>
<th>Name</th>
<th>Artist</th>
<th>Year</th>
</tr>
<xsl:apply-templates select="*/*/dict[1]/dict" >
<!-- sort by value of the name of the song -->
<xsl:sort select="key[. = 'Name']/following-sibling::*[1]" />
</xsl:apply-templates>
</table>
</xsl:template>
<xsl:template match="dict">
<tr>
<xsl:apply-templates select="*" />
</tr>
</xsl:template>
<xsl:template match="dict/key[. = 'Track ID' or . = 'Name' or . = 'Artist']">
<td>
<xsl:value-of select="following-sibling::*[1]" />
</td>
</xsl:template>
<!-- ignore what we do not need -->
<xsl:template match="dict/*" priority="-1" />
</xsl:stylesheet>
由于你没有提供有效的XML作为源文件(它有两个根元素),所以我发明了自己的符合原始代码的东西(即实际输出的东西),并添加了第二条记录以确保分类工作。一个友好的建议,如果您将来问XSLT问题,如果您包含一个(最小的)源文档,我们可以使用它来测试代码的修复,这将使我们更容易。
新的源文档:
<root>
<record>
<dict>
<key>5189</key>
<dict>
<key>Track ID</key><integer>5189</integer>
<key>Name</key><string>varsity jacket</string>
<key>Artist</key><string>bayou</string>
<key>Kind</key><string>MPEG audio file</string>
<key>Size</key><integer>3532008</integer>
<key>Total Time</key><integer>220107</integer>
<key>Date Modified</key><date>2015-07-26T14:04:34Z</date>
<key>Date Added</key><date>2015-07-26T14:04:17Z</date>
<key>Bit Rate</key><integer>128</integer>
<key>Sample Rate</key><integer>44100</integer>
<key>Play Count</key><integer>1</integer>
<key>Play Date</key><integer>3520959994</integer>
<key>Play Date UTC</key><date>2015-07-29T00:26:34Z</date>
<key>Skip Count</key><integer>2</integer>
<key>Skip Date</key><date>2015-08-29T05:12:33Z</date>
<key>Persistent ID</key><string>BE57D36AF01737E3</string>
<key>Track Type</key><string>File</string>
<key>Location</key><string>file:///Users/jason/Music/iTunes/iTunes%20Music/bayou/Unknown%20Album/varsity%20jacket.mp3</string>
<key>File Folder Count</key><integer>4</integer>
<key>Library Folder Count</key><integer>1</integer>
</dict>
<key>5190</key>
<dict>
<key>Track ID</key><integer>5190</integer>
<key>Name</key><string>some song</string>
<key>Artist</key><string>anton</string>
<key>Kind</key><string>MPEG audio file</string>
<key>Size</key><integer>3532008</integer>
<key>Total Time</key><integer>220107</integer>
<key>Date Modified</key><date>2015-07-26T14:04:34Z</date>
<key>Date Added</key><date>2015-07-26T14:04:17Z</date>
<key>Bit Rate</key><integer>128</integer>
<key>Sample Rate</key><integer>44100</integer>
<key>Play Count</key><integer>1</integer>
<key>Play Date</key><integer>3520959994</integer>
<key>Play Date UTC</key><date>2015-07-29T00:26:34Z</date>
<key>Skip Count</key><integer>2</integer>
<key>Skip Date</key><date>2015-08-29T05:12:33Z</date>
<key>Persistent ID</key><string>BE57D36AF01737E3</string>
<key>Track Type</key><string>File</string>
<key>Location</key><string>file:///Users/jason/Music/iTunes/iTunes%20Music/bayou/Unknown%20Album/varsity%20jacket.mp3</string>
<key>File Folder Count</key><integer>4</integer>
<key>Library Folder Count</key><integer>1</integer>
</dict>
</dict>
</record>
</root>
新的按名称排序输出:
<table>
<tr>
<th>Name</th>
<th>Artist</th>
<th>Year</th>
</tr>
<tr>
<td>5190</td>
<td>some song</td>
<td>anton</td>
</tr>
<tr>
<td>5189</td>
<td>varsity jacket</td>
<td>bayou</td>
</tr>
</table>
另请注意:您的第一个代码段为array/dict
,您的第二个代码段只有dict
,但您的XSLT使用dict/dict
,因此我更改了源代码结构以使其适合您的XSLT代码
你说:
按照原始XML文件末尾出现的用户指定顺序排序[...],而不是按照&#34;添加日期&#34;
您需要扩展我上面给出的示例。由于我不知道关于这部分的XML的结构,并且在问题中没有给出,我无法应用它。但是,我认为它将是底部的一个元素,所以应该很容易使用它。
例如,假设订单由/*/userorder/@by
给出,@by
包含与key
元素匹配的值,您可以这样做:
<xsl:sort select="key[. = /*/userorder/@by]/following-sibling::*[1]" />