[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

[xsl] Figuring out for-group-by


Subject: [xsl] Figuring out for-group-by
From: Barry Lay <blay@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 08 Jul 2004 19:00:33 -0400

I am running into trouble doing a transform with for-group-by. I am currently running Saxon 7.9.1 and am in the process of upgrading to 8.0. I thought I would post what I am up to in case my approach is wrong.

I have an XML file that looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>Major Version</key><integer>1</integer>
<key>Minor Version</key><integer>1</integer>
<key>Application Version</key><string>4.6</string>
<key>Music Folder</key><string>file://localhost/Volumes/120%20GB/Music/iTunes/iTunes%20Music/</string>
<key>Library Persistent ID</key><string>4AB531F8615308F0</string>
<key>Tracks</key>
<dict>
<key>35</key>
<dict>
<key>Track ID</key><integer>35</integer>
<key>Name</key><string>Last Time</string>
<key>Artist</key><string>Fuel</string>
<key>Album</key><string>Something Like Human</string>
<key>Genre</key><string>Rock</string>
<key>Kind</key><string>AIFF audio file</string>
<key>Size</key><integer>39233574</integer>
<!-- more key-value pairs -->
</dict>
<!-- more dict groups -->
</dict>
</dict>
</plist>


I have started out like this:

<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


<xsl:output method="xml" indent="yes"/>

<xsl:template match="/">
<xsl:for-each-group select="plist/dict/dict/dict" group-by="key[string() = 'Artist']/following-sibling::string[1]">
<xsl:variable name="artist" select="current-grouping-key()"/>
<xsl:for-each-group select="current-group()" group-by="key[string() = 'Album']/following-sibling::string[1]">
<xsl:variable name="album" select="current-grouping-key()"/>
<xsl:for-each-group select="current-group()" group-by="key[string() = 'Name']/following-sibling::string[1]">
<xsl:variable name="song" select="current-grouping-key()"/>
<xsl:element name="song">
<xsl:attribute name="artist">
<xsl:value-of select="$artist"/>
</xsl:attribute>
<xsl:attribute name="album">
<xsl:value-of select="$album"/>
</xsl:attribute>
<xsl:attribute name="name">
<xsl:value-of select="$song"/>
</xsl:attribute>
<xsl:attribute name="key">
<xsl:value-of select="current-group()/key[string() = 'Track ID']/following-sibling::integer[1]"/>
</xsl:attribute>
</xsl:element>
</xsl:for-each-group>
</xsl:for-each-group>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>


In case you are wondering, I am trying to fix my iTunes library which has duplicate entries in it as a result of converting everything to Apple Lossless encoding. Looking at the results I can see that the attribute labelled 'key' gives me all of the track Ids matching the compound key. The fact that there are more than one is the issue. What I would like to do is identify the track Id(s) associated with the entry that has

<key>Kind</key><string>Apple Lossless audio file</string>

within it. I tried moving up a level in the initial select like this:

<xsl:for-each-group select="plist/dict/dict" group-by="dict/key[string() = 'Artist']/following-sibling::string[1]">

to see if I can see if I can get the enclosing dict element as current-group but it took a long time and gave me nothing.

My main problem is that I am having trouble visualizing what I am working with inside of the inner for-each-group.

Thanks.


Current Thread
Keywords
xml