I am writing xsl stylesheet to extract information from iTunes Music Library. xml file.
我正在编写xsl样式表以从iTunes Music Library中提取信息。 xml文件。
I want to store track information of playlists in an array and later iterate over them to get more information. I am confused how to store values in an array in xslt?
我想在一个数组中存储播放列表的轨道信息,然后迭代它们以获取更多信息。我很困惑如何在xslt中的数组中存储值?
My attempt is here:
我的尝试在这里:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:template match="/">
<xsl:variable name="tracks"
select="plist/dict/array/dict[integer[preceding-sibling::key[1]='Playlist ID']=6711]/array/dict/integer[preceding-sibling::key[1]='Track ID']" />
<!-- I want to iterate over that array outside for-each loop and gather more information, The below code is not working.-->
<xsl:for-each select="$tracks">
<xsl:value-of select="." />
<xsl:value-of select="plist/dict/dict/dict[integer[preceding-sibling::key[1]='Track ID']="."]/integer[preceding-sibling::key[1]='Track ID']" />
<xsl:value-of select="plist/dict/dict/dict[integer[preceding-sibling::key[1]='Track ID']="."]/string[preceding-sibling::key[1]='Name']" />
<xsl:value-of select="plist/dict/dict/dict[integer[preceding-sibling::key[1]='Track ID']="."]/string[preceding-sibling::key[1]='Total Time']" />
<xsl:value-of select="plist/dict/dict/dict[integer[preceding-sibling::key[1]='Track ID']="."]/string[preceding-sibling::key[1]='Location']" />
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
A typical Track Ids which are populated in array variable "tracks", are represented in below manner in itunes list. I want to list Name, Location, time infor for each Track Ids stored in the array. Something wrong with my conditions.
在数组变量“轨道”中填充的典型轨道ID在itunes列表中以下面的方式表示。我想列出存储在数组中的每个Track Ids的Name,Location,time infor。我的情况有问题。
<plist>
<dict>
<dict>
<dict>
<key>Track ID</key>
<integer>1633</integer>
<key>Name</key>
<string>Right here</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/track1633.mp3</string>
</dict>
<dict>
<!-- Next Track info -->
</dict>
</dict>
</dict>
</plist>
Here I am stuck. Can any XSLT experts here to help me out?
我被困在这里。任何XSLT专家都可以帮助我吗?
1 个解决方案
#1
3
You could just create a variable and populate its results with an XPath expression all in one go rather than interate through to build it.
您可以创建一个变量并使用XPath表达式一次性填充其结果,而不是通过构建它来进行交互。
<xsl:variable name="tracks"
select="plist/dict/array/dict[integer[preceding-sibling::key[1]='Playlist ID']=6711]/array/dict/integer[preceding-sibling::key[1]='Track ID']" />
Alternatively you could use xsl:keys at the begining of your document, I'm assuming that the path to the track information is /plist/dict/array/dict
with the first dict key being Tracks
或者你可以在你的文档的开头使用xsl:keys,我假设轨道信息的路径是/ plist / dict / array / dict,第一个dict键是Tracks
<xsl:key
name="playlists"
match="plist/dict/array/dict/array/dict/integer[preceding-sibling::key[1]='Track ID']"
use="../../../integer[preceding-sibling::key[1]='Playlist ID']"
/>
<xsl:key
name="tracks"
match="/plist/dict/array[preceding-sibling::key[1]='Tracks']/dict"
use="integer[preceding-sibling::key[1]='Track ID']"
/>
This allows you to do key('playlists','4555')
to return all the trackids associated with playlist id 4555
and also key('tracks','1234')
to get the dict object associated with track id 1234
这允许您执行键('播放列表','4555')以返回与播放列表ID 4555相关联的所有轨迹以及键('轨迹','1234')以获取与轨道ID 1234相关联的dict对象
You can then combine the two together to do
然后你可以将两者结合起来做
<xsl:variable "mytracks" select="key('tracks',key('playlists','6711'))" />
That will set $mytracks
equal to the array of dict objects for the tracks in playlist 6711. It aslo has the benefits of the speed enhancement granted by xsl:key
这将设置$ mytracks等于播放列表6711中的曲目的dict对象数组。它还具有xsl:key授予的速度增强的好处
EDIT UPDATE----
I'm guessing you are trying to make a CSV from this so this code should do that
我猜你正试图从这里制作一个CSV,所以这段代码应该这样做
<?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:key
name="playlists"
match="plist/dict/array/dict/array/dict/integer[preceding-sibling::key[1]='Track ID']"
use="../../../integer[preceding-sibling::key[1]='Playlist ID']"
/>
<xsl:key
name="tracks"
match="/plist/dict/dict/dict"
use="integer[preceding-sibling::key[1]='Track ID']"
/>
<xsl:template match="/">
<xsl:variable name="myplaylist" select="'6711'"/>
<xsl:for-each select="key('tracks',key('playlists',$myplaylist))">
<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:template>
</xsl:stylesheet>
to match a different playlist id just change the value of myplaylist
匹配不同的播放列表ID只需更改myplaylist的值
--EDIT Version without xsl:key
,again just alter the value of the myplaylist variable
- 不带xsl:key的EDED版本,再次只是改变myplaylist变量的值
--EDIT Now mofified to original sort order of playlist --EDIT Attempt to work around Qt Limitations
--EDIT现在mofified到播放列表的原始排序顺序--EDIT尝试解决Qt限制
<?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: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>
#1
3
You could just create a variable and populate its results with an XPath expression all in one go rather than interate through to build it.
您可以创建一个变量并使用XPath表达式一次性填充其结果,而不是通过构建它来进行交互。
<xsl:variable name="tracks"
select="plist/dict/array/dict[integer[preceding-sibling::key[1]='Playlist ID']=6711]/array/dict/integer[preceding-sibling::key[1]='Track ID']" />
Alternatively you could use xsl:keys at the begining of your document, I'm assuming that the path to the track information is /plist/dict/array/dict
with the first dict key being Tracks
或者你可以在你的文档的开头使用xsl:keys,我假设轨道信息的路径是/ plist / dict / array / dict,第一个dict键是Tracks
<xsl:key
name="playlists"
match="plist/dict/array/dict/array/dict/integer[preceding-sibling::key[1]='Track ID']"
use="../../../integer[preceding-sibling::key[1]='Playlist ID']"
/>
<xsl:key
name="tracks"
match="/plist/dict/array[preceding-sibling::key[1]='Tracks']/dict"
use="integer[preceding-sibling::key[1]='Track ID']"
/>
This allows you to do key('playlists','4555')
to return all the trackids associated with playlist id 4555
and also key('tracks','1234')
to get the dict object associated with track id 1234
这允许您执行键('播放列表','4555')以返回与播放列表ID 4555相关联的所有轨迹以及键('轨迹','1234')以获取与轨道ID 1234相关联的dict对象
You can then combine the two together to do
然后你可以将两者结合起来做
<xsl:variable "mytracks" select="key('tracks',key('playlists','6711'))" />
That will set $mytracks
equal to the array of dict objects for the tracks in playlist 6711. It aslo has the benefits of the speed enhancement granted by xsl:key
这将设置$ mytracks等于播放列表6711中的曲目的dict对象数组。它还具有xsl:key授予的速度增强的好处
EDIT UPDATE----
I'm guessing you are trying to make a CSV from this so this code should do that
我猜你正试图从这里制作一个CSV,所以这段代码应该这样做
<?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:key
name="playlists"
match="plist/dict/array/dict/array/dict/integer[preceding-sibling::key[1]='Track ID']"
use="../../../integer[preceding-sibling::key[1]='Playlist ID']"
/>
<xsl:key
name="tracks"
match="/plist/dict/dict/dict"
use="integer[preceding-sibling::key[1]='Track ID']"
/>
<xsl:template match="/">
<xsl:variable name="myplaylist" select="'6711'"/>
<xsl:for-each select="key('tracks',key('playlists',$myplaylist))">
<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:template>
</xsl:stylesheet>
to match a different playlist id just change the value of myplaylist
匹配不同的播放列表ID只需更改myplaylist的值
--EDIT Version without xsl:key
,again just alter the value of the myplaylist variable
- 不带xsl:key的EDED版本,再次只是改变myplaylist变量的值
--EDIT Now mofified to original sort order of playlist --EDIT Attempt to work around Qt Limitations
--EDIT现在mofified到播放列表的原始排序顺序--EDIT尝试解决Qt限制
<?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: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>