问题
I am parsing itunes library xml file. The information in it is stored in following manner. Tracks information are stored separately and playlist information are stored differently. A playlist consists of different tracks.
A typical itunes playlist looks like below.
<?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>
Now I have written XSL stylesheet to get detail information of all tracks of given playlists. But the problem is, Under playlists tracks can be in random order and under track informations Ids are stored in sorted manner. When I use Xpath expressions I don't get informations in the same order as mentioned in playlists.
Here's my 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>
</xsl:text>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
But wit above XSLT I see only first element of the playlists. Can anybody point out whats the mistake? Any XSLT experts please enlighten me.
With the above XML the output dumps like below:
<Track ID>,<Track Name>,<duration>,<location>
As we can see, in <plist><dict><dict><dict>
, All track information are stored sorted by Track Ids. But Playlists contains tracks which are not sorted. so when I query for track infos into <plist><dict><dict><dict>
from the track ids which I got from playlists plist/dict/array/dict/array/dict
, I get sorted information. I want it in the same order as mentioned in playlist.
currently I get only first value. output: 2413,song_2,358870,/Users/rakesh/Music/iTunes/iTunes%20Media/Music/track2413.mp3
expected: 2413,song_2,358870,/Users/rakesh/Music/iTunes/iTunes%20Media/Music/track2413.mp3 1769,song_1,358870,/Users/rakesh/Music/iTunes/iTunes%20Media/Music/track1769.mp3
回答1:
This appears to be a problem with qt not liking the iterating of nested variables, here is a reworked version
<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>
</xsl:text>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
来源:https://stackoverflow.com/questions/7146775/xslt-iterating-over-variable-array-to-get-sorted-result-not-working