Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何按给定顺序对XML进行排序?(干扰导出的iTunes播放列表)_Xml_Xslt_Itunes - Fatal编程技术网

如何按给定顺序对XML进行排序?(干扰导出的iTunes播放列表)

如何按给定顺序对XML进行排序?(干扰导出的iTunes播放列表),xml,xslt,itunes,Xml,Xslt,Itunes,在iTunes中,当您以XML格式导出播放列表时,它会自动以“添加日期”而不是用户订购顺序的方式导出。在XML文件的末尾,它列出了播放列表的顺序,用户按歌曲ID排序,如下所示: <key>Playlist Items</key> <array> <dict> <key>Track ID</key><integer>53

在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>
播放列表项目
轨道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]" />