[xsl] Multiple hierarchy grouping (warning: longish)

Subject: [xsl] Multiple hierarchy grouping (warning: longish)
From: Eric <kiteeatingtree@xxxxxxxxxxxxx>
Date: Thu, 27 May 2010 22:21:26 -0600
Dear XSL List,

I would very much appreciate a little guidance over a problem that has already
caused me enough grief to cause me to rend my clothes.  The problem is an
incarnation of the problem of converting flat XML into structured XML,
specifically EAD.  My problem is with allowing one layer to have multiple
parents.  So, in this sample XML:

	<Record>
		<Series>3</Series>
		<Box>13</Box>
		<Folder>1</Folder>
		<FolderTitle>Chamber music</FolderTitle>
		<FolderID>227</FolderID>
		<Item>Piano Trio Quartet</Item>
	</Record>

The resulting structured XML will have the following rules:
* Each folder may be the child of only one box
* Each folder may be part of only one series/subseries.
* A box may contain folders representing more than one series/subseries

My XML is exported such that each time a new layer is created, multiple
<record>s are producedwhen a <folder> has three <item>s, three different
<record>s are created.  So given the following XML:

	<Record>
		<Series>2</Series>
		<Subseries>1</Subseries>
		<Box>12</Box>
		<Folder>17</Folder>
		<FolderTitle>Symphonic Poem</FolderTitle>
		<FolderID>223</FolderID>
	</Record>
	<Record>
		<Series>2</Series>
		<Subseries>1</Subseries>
		<Box>12</Box>
		<Folder>18</Folder>
		<FolderTitle>Requeim Mass</FolderTitle>
		<FolderID>224</FolderID>
	</Record>
	<Record>
		<Series>2</Series>
		<Subseries>2</Subseries>
		<Box>12</Box>
		<Folder>19</Folder>
		<FolderTitle>Symphony no. 4</FolderTitle>
		<FolderID>225</FolderID>
	</Record>
	<Record>
		<Series>3</Series>
		<Box>12</Box>
		<Folder>20</Folder>
		<FolderTitle>Symphony no. 5</FolderTitle>
		<FolderID>226</FolderID>
	</Record>
	<Record>
		<Series>3</Series>
		<Box>13</Box>
		<Folder>1</Folder>
		<FolderTitle>Chamber music</FolderTitle>
		<FolderID>227</FolderID>
		<Item>String Quartet</Item>
	</Record>
	<Record>
		<Series>3</Series>
		<Box>13</Box>
		<Folder>1</Folder>
		<FolderTitle>Chamber music</FolderTitle>
		<FolderID>227</FolderID>
		<Item>String Quartet no. 2</Item>
	</Record>
	<Record>
		<Series>3</Series>
		<Box>13</Box>
		<Folder>1</Folder>
		<FolderTitle>Chamber music</FolderTitle>
		<FolderID>227</FolderID>
		<Item>Piano Trio Quartet</Item>
	</Record>

...I would like the resulting XML structured as follows:

Series 2
	Subseries 1
		Box 12, Folder 17: Symphonic Poem
		Box 12, Folder 18: Requeim Mass
	Subseries 2
		Box 12, Folder 19: Symphony no. 4
Series 3
	Box 12, Folder 20: Symphony no. 5
	Box 13, Folder 1: Chamber music
		String Quartet
		String Quartet no. 2
		Piano Trio

I have come close but not quite won the cigar.  My best attempt used the
<xsl:for-each-group>, but all the <record>s with <Box>=12 were incorrectly
grouped together, as follows:

XSLT:

<xsl:for-each-group select="//Record" group-by="Box">
	<xsl:if test="Series=$SER">
		<xsl:choose>
			<xsl:when test="Folder">
				<xsl:variable name="BOX" select="Box"/>
				<xsl:for-each-group select="//Record" group-by="FolderID">
					<xsl:if test="Box=$BOX">
						<xsl:call-template name="File-Folder-Nosub"/>
						<!--the template called produces the output for the box and folder-->
					</xsl:if>
				</xsl:for-each-group>
			</xsl:when>
			<......./>
		</xsl:choose>
	</xsl:if>
</xsl:for-each-group>

Result:


Series 2
	Subseries 1
		Box 12, Folder 17: Symphonic Poem
		Box 12, Folder 18: Requeim Mass
	Subseries 2
		Box 12, Folder 19: Symphony no. 4
		Box 12, Folder 20: Symphony no. 5
Series 3
	Box 13, Folder 1: Chamber music
		String Quartet
		String Quartet no. 2
		Piano Trio


Folder 20 should be under series 3, but is instead grouped with the rest of
box 12 under series 2/subseries 2.  Using a different approach, I was able to
get the boxes to group properly, but was unable to de-duplicate at the item
level:


<xsl:for-each select="//Record">
	<xsl:if test="Series=$SER">
		<xsl:choose>
			<xsl:when test="Folder">
				<xsl:call-template name="File-Folder-Nosub"/>
			</xsl:when>
			<...../>
		</xsl:choose>
	</xsl:if>
</xsl:for-each>


Series 2
	Subseries 1
		Box 12, Folder 17: Symphonic Poem
		Box 12, Folder 18: Requeim Mass
	Subseries 2
		Box 12, Folder 19: Symphony no. 4
		Box 12, Folder 20: Symphony no. 5
Series 3
	Box 13, Folder 1: Chamber music
		String Quartet
		String Quartet no. 2
		Piano Trio
	Box 13, Folder 1: Chamber music
		String Quartet
		String Quartet no. 2
		Piano Trio
	Box 13, Folder 1: Chamber music
		String Quartet
		String Quartet no. 2
		Piano Trio

Is there a way to group using <xsl:for-each-group> so that the grouping can be
split between series in a case like this?  Clearly I'm using XSLT 2.0 right
now, though I'm wondering a little if I'm going to need to use a 1.0 Muenchian
method.    More likely, I just don't understand grouping like I need to, and
am just missing something silly.

Thanks in advance for any help.  For the record, I did search the archives and
didn't find anything that seemed to answer my question.  Or it did and I
didn't recognize it as such.  Apologies if this is something that's been
discussed.

Thanks!
Eric

Current Thread