[xsl] recursive sub-grouping

Subject: [xsl] recursive sub-grouping
From: Robin Wyles <rob@xxxxxxxxxxxxxx>
Date: Mon, 23 Aug 2004 14:50:07 +0200
Hi,

I am stuck on a transformation that requires me to group and sub-group a set of nodes based on their child nodes. My starting XML is as follows:

-------------- SOURCE ---------------
<?xml version="1.0"?>
<video-files>
	<video-file>
		<language>English</language>
		<format>Real</format>
		<bandwidth>Low</bandwidth>
	</video-file>
	<video-file>
		<language>English</language>
		<format>Real</format>
		<bandwidth>High</bandwidth>
	</video-file>
	<video-file>
		<language>English</language>
		<format>QuickTime</format>
		<bandwidth>Low</bandwidth>
	</video-file>
	<video-file>
		<language>English</language>
		<format>QuickTime</format>
		<bandwidth>High</bandwidth>
	</video-file>
	<video-file>
		<language>French</language>
		<format>Real</format>
		<bandwidth>Low</bandwidth>
	</video-file>
	<video-file>
		<language>French</language>
		<format>Real</format>
		<bandwidth>High</bandwidth>
	</video-file>
	<video-file>
		<language>French</language>
		<format>QuickTime</format>
		<bandwidth>Low</bandwidth>
	</video-file>
	<video-file>
		<language>French</language>
		<format>QuickTime</format>
		<bandwidth>High</bandwidth>
	</video-file>
</video-files>
-------------------------

And the final XML is to be as follows:

---------- FINAL ---------
<?xml version="1.0"?>
<languages>
	<language>
		<name>English</name>
		<formats>
			<format>
				<name>Real</name>
				<bandwidths>
					<bandwidth>
						<name>High</name>
					</bandwidth>
					[...]
				</bandwidths>				
			</format>
			[...]
		</formats>
	<language>
	[...]
</languages>
-----------------------------

I have searched the list for some pointers to a solution for this problem and I have found plenty on grouping and sub-grouping but I have had limited success in applying the techniques to my situation. The initial grouping of the languages is no problem, but I am not sure how to approach the sub-grouping on the current language group into format groups, and then sub-group each of these into the bandwidth groups. I have a feeling that I need to generate keys for the different language/format/bandwidth combinations, but I am not sure how to implement this. For what it's worth my current XSLT is as follows:

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


<xsl:key name="languages" match="video-file" use="language"/>
<xsl:key name="formats" match="video-file" use="concat(language, '+', format)"/>
<xsl:key name="bandwidths" match="video-file" use="concat(language, '+', format, '+', bandwidth)"/>


<xsl:template match="video-files">
<languages>
<xsl:for-each select="video-file[generate-id(.)=generate-id(key('languages', language)[1])]">
<xsl:for-each select="key('languages', language)">
<xsl:sort select="format"/>
<language>
<xsl:if test="position() = 1">
<name><xsl:value-of select="language"/></name>
</xsl:if>
<formats>
<!--- Need to do sub grouping here -->
</formats>
</language>
</xsl:for-each>
</xsl:for-each>
</languages >
</xsl:template>
</xsl:stylesheet>
--------------------------------


If anyone has any advice on the best way to approach this problem (XSLT 1.0 only if possible), I would appreciate it.

Thanks,

Robin

Current Thread