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.