XSLT:迭代变量数组以使得排序结果不起作用。

时间:2011-08-22 11:27:00

标签: xslt xpath xslt-2.0

我正在解析itunes库xml文件。其中的信息以下列方式存储。 轨道信息分开存储,播放列表信息以不同方式存储。播放列表由不同的曲目组成。

典型的itunes播放列表如下所示。

  <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
   <dict>
         <dict>
               <dict>
                  <key>Track ID</key>
                  <integer>1769</integer>
                  <key>Name</key>
                  <string>song_1</string>
                  <key>Kind</key>
                  <string>MPEG audio file</string>
                  <key>Total Time</key>
                  <integer>358870</integer>
                  <key>Location</key>
                  <string>/Users/rakesh/Music/iTunes/iTunes%20Media/Music/track1769.mp3</string>
                </dict>
               <dict>
                  <key>Track ID</key>
                  <integer>2413</integer>
                  <key>Name</key>
                  <string>song_2</string>
                  <key>Kind</key>
                  <string>MPEG audio file</string>
                  <key>Total Time</key>
                  <integer>358870</integer>
                  <key>Location</key>
                  <string>/Users/rakesh/Music/iTunes/iTunes%20Media/Music/track2413.mp3</string>
                </dict>

           </dict>

    <array>
        <dict>
            <key>Name</key><string>Library</string>
            <key>Playlist ID</key><integer>4053</integer>
            <array>
                <dict>
                    <key>Track ID</key><integer>2413</integer>
                </dict>
                <dict>
                    <key>Track ID</key><integer>1769</integer>
                </dict>
            </array>
        </dict>
        <dict>
            <key>Name</key><string>Movies</string>
            <key>Playlist ID</key><integer>6536</integer>
        </dict>
        <dict>
            <key>Name</key><string>TV Shows</string>
            <key>Playlist ID</key><integer>6539</integer>
        </dict>
        <dict>
            <key>Name</key><string>iTunes U</string>
            <key>Playlist ID</key><integer>5331</integer>
        </dict>
        <dict>
            <key>Name</key><string>Books</string>
            <key>Playlist ID</key><integer>6542</integer>
        </dict>
        <dict>
            <key>Name</key><string>Genius</string>
            <key>Playlist ID</key><integer>6551</integer>
        </dict>
        <dict>
            <key>Name</key><string>On-The-Go 1</string>
            <key>Playlist ID</key><integer>6568</integer>
            <array>
                <dict>
                    <key>Track ID</key><integer>2877</integer>
                </dict>
                <dict>
                    <key>Track ID</key><integer>2345</integer>
                </dict>
            </array>
        </dict>
    </array>
  </dict>
</plist>

现在我编写了XSL样式表来获取给定播放列表的所有曲目的详细信息。但问题是,在播放列表下,轨道可以按随机顺序和轨道下信息Ids以有序的方式存储。当我使用Xpath表达式时,我没有按照播放列表中提到的顺序获取信息。

这是我的XSL。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="text" />

  <xsl:template match="/">
    <xsl:variable name="myplaylist" select="'4053'"/>
    <xsl:variable name="playlist_tracks" select="/plist/dict/array/dict[integer[preceding-sibling::key[1]='Playlist ID']=$myplaylist]/array/dict/integer[preceding-sibling::key[1]='Track ID']" />
    <xsl:variable name="tracks" select="/plist/dict/dict/dict[integer[preceding-sibling::key[1]='Track ID']=$playlist_tracks]" />

<xsl:for-each select="$playlist_tracks">
  <xsl:variable select="." name="current" />
    <xsl:for-each select ="$tracks[integer[preceding-sibling::key[1]='Track ID']=$current]" >
       <xsl:value-of select="integer[preceding-sibling::key[1]='Track ID']"/>
         <xsl:text>,</xsl:text>
        <xsl:value-of select="string[preceding-sibling::key[1]='Name']"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="integer[preceding-sibling::key[1]='Total Time']"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="string[preceding-sibling::key[1]='Location']"/>
        <xsl:text>&#xa;</xsl:text>
      </xsl:for-each>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

但是在XSLT之上我只看到了播放列表的第一个元素。任何人都可以指出错误是什么?任何XSLT专家都请赐教。

使用上面的XML输出转储如下: <Track ID>,<Track Name>,<duration>,<location>

正如我们所看到的,在<plist><dict><dict><dict>中,所有曲目信息都按Track Ids排序。但播放列表包含未排序的曲目。因此,当我从播放列表<plist><dict><dict><dict>中获取的曲目ID中查询曲目信息plist/dict/array/dict/array/dict时,我会获得排序信息。我希望它与播放列表中提到的顺序相同。

目前我只获得第一个价值。 输出: 2413,song_2,358870,/用户/勒凯什/音乐/ iTunes的/ iTunes的%20Media /音乐/ track2413.mp3

预期: 2413,song_2,358870,/用户/拉克什/音乐/ iTunes的/ iTunes的%20Media /音乐/ track2413.mp3 1769年,song_1,358870,/用户/勒凯什/音乐/ iTunes的/ iTunes的%20Media /音乐/ track1769.mp3

1 个答案:

答案 0 :(得分:1)

这似乎是qt不喜欢迭代嵌套变量的问题,这里是一个重写版本

          

<xsl:template match="/"> 
  <xsl:variable name="myplaylist" select="'4053'"/> 
  <xsl:variable name="playlist_tracks" select="/plist/dict/array/dict[integer[preceding-sibling::key[1]='Playlist ID']=$myplaylist]/array/dict/integer[preceding-sibling::key[1]='Track ID']" /> 
  <xsl:for-each select="$playlist_tracks"> 
    <xsl:variable select="." name="current" /> 
      <xsl:for-each select ="/plist/dict/dict/dict[integer[preceding-sibling::key[1]='Track ID']=$current]" > 
        <xsl:value-of select="integer[preceding-sibling::key[1]='Track ID']"/> 
        <xsl:text>,</xsl:text> 
        <xsl:value-of select="string[preceding-sibling::key[1]='Name']"/> 
        <xsl:text>,</xsl:text> 
        <xsl:value-of select="integer[preceding-sibling::key[1]='Total Time']"/> 
        <xsl:text>,</xsl:text> 
        <xsl:value-of select="string[preceding-sibling::key[1]='Location']"/> 
        <xsl:text>&#xa;</xsl:text> 
      </xsl:for-each> 
    </xsl:for-each> 
  </xsl:template> 
</xsl:stylesheet>