XSLT: перебор массива переменных для получения отсортированного результата не работает. - PullRequest
0 голосов
/ 22 августа 2011

Я анализирую XML-файл библиотеки itunes.Информация в нем хранится следующим образом.Информация о дорожках хранится отдельно, а информация о списках воспроизведения хранится по-разному.Список воспроизведения состоит из разных дорожек.

Типичный список воспроизведения 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, чтобы получить подробную информацию обо всех дорожках данных списков воспроизведения.Но проблема в том, что под списками воспроизведения треки могут быть в произвольном порядке, а под данными треков идентификаторы хранятся в отсортированном виде.Когда я использую выражения 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> вся информация о треках хранится, отсортированная по трекуИдентификаторы.Но плейлисты содержат треки, которые не отсортированы.поэтому, когда я запрашиваю информацию о дорожке в <plist><dict><dict><dict> из идентификаторов дорожек, которые я получил из списков воспроизведения plist/dict/array/dict/array/dict, я получаю отсортированную информацию.Я хочу, чтобы он был в том же порядке, как указано в списке воспроизведения.

В настоящее время я получаю только первое значение.вывод: 2413, song_2,358870, / Users / rakesh / Music / iTunes / iTunes% 20Media / Music / track2413.mp3

Ожидается: 2413, song_2,358870, / Users / rakesh / Music / iTunes / iTunes% 20Media / Music / track2413.mp3 1769, song_1,358870, / Users / rakesh / Музыка / iTunes / iTunes% 20Media / Music / track1769.mp3

1 Ответ

1 голос
/ 23 августа 2011

Похоже, проблема в том, что 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> 
...