[xsl] for-each-group and result-document splitting to less files.

Subject: [xsl] for-each-group and result-document splitting to less files.
From: "James Cummings" <cummings.james@xxxxxxxxx>
Date: Fri, 5 Sep 2008 13:50:23 +0100
Hiya,

I'm doing a double xsl:-for-each-grouping where the first groups a set
of elements without a particular attribute alphabetically by the first
letter, and the second, inside an an xsl:result-document groups
individual instances of that element. Currently this is working fine
with the following in the midst of a larger template:

====
<div>
<head>Alphabetical List</head>
<list type="unordered">
<!-- grouping on first letter, any tei:persName[not(@key)] in a
collection() of documents -->
<xsl:for-each-group select="$persNamesWithoutKey"
   group-by="substring(normalize-space(lower-case(.)),1,1)">
<xsl:sort select="current-grouping-key()"/>
<item>
<ref target="{concat('/projects/foo/web/persNameWithoutKey/file-',
current-grouping-key(), '.xml')}">
   persName elements without a @key starting with: <xsl:value-of
select="current-grouping-key()"/></ref>
</item>
<!-- new file replacing but square bracket or space in name  -->
<xsl:result-document href="file-{x:replace(current-grouping-key(),
('\[', 'squarebracket', ' ', ''))}.xml">
<TEI xmlns="http://www.tei-c.org/ns/1.0";>
<teiHeader>
<!-- TEI Header here -->
</teiHeader>
<text>
<body>
   <list>
   <xsl:for-each-group select="current-group()"
group-by="normalize-space(lower-case(.))">
       <xsl:sort select="current-grouping-key()"/>
       <xsl:variable name="count" select="count(current-group())"/>
       <item>
       <xsl:value-of select="concat(current-grouping-key(), ' -- ',
$count, '  ' )"/>

       <list type="hideItems">
           <xsl:for-each select="current-group()">
               <xsl:variable name="thisDate"
select="./ancestor::tei:ab[@type='foo']//tei:date[1]/@when"/>
               <item>
                   <ref target="{concat('/projects/foo/',
substring-before($thisDate, '-'), '.xml#d',$thisDate)}">
                       <xsl:value-of select="$thisDate"/>
                   </ref>
               </item>
           </xsl:for-each>
       </list>

       </item>
   </xsl:for-each-group>
</list>
</body>
</text>
</TEI>
</xsl:result-document>
</xsl:for-each-group>
</list>
</div>
=====

Now what I want to do is produce the same lists, but instead of 40-odd
files (alphabet + numbers +punctuation characters)
I want to break it into 5 files for punctuation&numbers, a-f, g-l,
m-r, and s-z.  Obviously inside the files I want it still to be sorted
into individual alphabetic groups. (i.e. a, b, c, all as separate divs
or lists or something).

Is there a way with:
<xsl:for-each-group select="$persNamesWithoutKey"
 group-by="substring(normalize-space(lower-case(.)),1,1)">
to say something like [^,$,#,0-9], [a-f], [g-l] [m-r] [s-z] as mulitple
values for group-by? Or somehow using collation?  Or should there be
another grouping? And how would this then affect the
<xsl:result-document href="file-{x:replace(current-grouping-key(),
('\[', 'squarebracket', ' ', ''))}.xml">?  (x:replace here is a
function that replacing [ with the phrase 'squarebracket' that I use
elsewhere, so was just handy to use it here since saxon didn't like
creating a filename with [ in it for some reason.)

Any suggestions appreciated.

Thanks,
-James

Current Thread