如何按给定顺序对XML进行排序?(干扰导出的iTunes播放列表)
在iTunes中,当您以XML格式导出播放列表时,它会自动以“添加日期”而不是用户订购顺序的方式导出。在XML文件的末尾,它列出了播放列表的顺序,用户按歌曲ID排序,如下所示:如何按给定顺序对XML进行排序?(干扰导出的iTunes播放列表),xml,xslt,itunes,Xml,Xslt,Itunes,在iTunes中,当您以XML格式导出播放列表时,它会自动以“添加日期”而不是用户订购顺序的方式导出。在XML文件的末尾,它列出了播放列表的顺序,用户按歌曲ID排序,如下所示: <key>Playlist Items</key> <array> <dict> <key>Track ID</key><integer>53
<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>
播放列表项目
轨道ID5365
轨道ID5317
轨道ID5235
我使用以下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>
名称
艺术家
年
我想知道如何编辑XSL以转换播放列表,从而根据原始XML文件末尾出现的用户给定顺序而不是“添加日期”对所有内容重新排序?
编辑-添加更多原始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>
5189
轨道ID5189
名牌大学运动夹克
艺术家Bayou
一种mpeg音频文件
尺寸3532008
总时间220107
日期修改2015-07-26T14:04:34Z
添加日期2015-07-26T14:04:17Z
比特率128
抽样率44100
播放计数1
播放日期3520959994
播放日期UTC2015-07-29T00:26:34Z
跳过计数2
跳过日期2015-08-29T05:12:33Z
持久性IDBE57D36AF01737E3
轨道类型文件
Locationfile:///Users/jason/Music/iTunes/iTunes%20Music/bayou/Unknown%20Album/varsity%20jacket.mp3
文件夹计数4
库文件夹计数1
基本但友好的代码建议:如果您能满足xsl:apply templates
的要求,请不要在上下文中使用xsl:call template
,因为这会限制您的流程并使代码复杂化
查看我的编辑。我采用了您的结构,但通过删除xsl:call模板
简化了结构,该模板没有任何其他用途
要排序,只需使用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>
对代码的基本但友好的建议:如果您能满足
xsl:apply templates
,请不要在上下文中使用xsl:call template
,因为这会限制您的流程并使代码复杂化
查看我的编辑。我采用了您的结构,但通过删除xsl:call模板
简化了结构,该模板没有任何其他用途
要排序,只需使用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示例?理想的情况下,一个与一些歌曲中!非常感谢。当然可以您可以看到,在XSL中,我只使用了3个东西,并在转换中放弃了其余的东西。在示例中,我还添加了更多关于XML的第一部分的内容,“根据原始XML文件末尾显示的用户给定顺序,我在XML中没有看到类似的内容。请给出一个最小但完整的示例:是否可以编辑您的问题以显示更具代表性的输入XML示例?理想的情况下,一个与一些歌曲中!非常感谢。当然可以您可以看到,在XSL中,我只使用了3个东西,并在转换中放弃了其余的东西。在示例中,我还添加了更多关于XML的第一部分的内容,“根据原始XML文件末尾显示的用户给定顺序,我在XML中没有看到类似的内容。请发布一个简单但完整的例子:非常感谢!我在这方面仍然很笨拙,因为我今天才开始学习。我想我的最后一个问题是:如果我想按照一个只包含歌曲ID的列表进行排序,我该怎么做?@user3491271这并不像人们期望的那么简单,因为它取决于你如何接收这个列表(逗号分隔?、节点集?、变量?、源结构的一部分?),您使用的XSLT版本等。您最好使用清晰的格式良好的输入、预期的输出、当前的输出和到目前为止(部分工作)的XSLT。@user3491271:ps,如果我的答案对您有帮助,请随意投票并接受它作为答案。如果你今天刚开始学习,我想你已经做得很好了!一个很好的教程视频,为您节省了大量的尝试和错误问题。快乐编码!非常感谢你!我在这方面仍然很笨拙,因为我今天才开始学习。我想我的最后一个问题是:如果我想按照一个只包含歌曲ID的列表进行排序,我该怎么做?@user3491271这并不像人们期望的那么简单,因为它取决于你如何接收这个列表(逗号分隔?、节点集?、变量?、源结构的一部分?),您使用的XSLT版本等。您最好使用清晰的格式良好的输入、预期的输出、当前的输出和到目前为止(部分工作)的XSLT。@user3491271:ps,如果我的答案对您有帮助,请随意投票并接受它作为答案。如果你今天刚开始学习,我想你已经做得很好了!一个很好的教程视频,为您节省了大量的尝试和错误问题。快乐编码!
<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>
<xsl:sort select="key[. = /*/userorder/@by]/following-sibling::*[1]" />