xsl-list
[Top] [All Lists]

[xsl] Multiple hierarchy grouping (warning: longish)

2010-05-27 23:21:50
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 produced—when 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
--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>