[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Multiple grouping with substrings

Subject: Re: Multiple grouping with substrings
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Tue, 13 Aug 2002 19:45:56 +0100
xsl for each substring
Hi Ben,

> I have a grouping problem I cannot work out. I have done a couple of
> stylesheets with keys but this one has me befuddled.
>
> I am having trouble declaring and using a key like this; (I am new
> to keys so go easy here)
>
> <xsl:key name="xprogs" match="doc/prog[contains(.,'msx']"
>          use="substring(.,4,1)"/>
>
> My algorithm is 
>         a). Group by 3rd character of prog node ie 'x'  in msx123 followed
> by 'y' in msy123
>
>         b). For each unique 4th character of prog node list prog nodes 4 (or
>         ideally custom value)
>         per line        separated by a single space (produce new line when a
>         different 4th character
>         encountered).

OK, it sounds as though you want to group by the third *and* fourth
characters. You want to group *all* the prog elements rather than just
those that contain 'msx', so your match attribute should match all
prog elements. And if you want the third and fourth characters, then
you need substring(., 3, 2):

<xsl:key name="progs" match="prog" use="substring(., 3, 2)" />

Then you have to think about selecting all those prog elements that
have a unique letter-number combination: if they're the first prog
with that particular letter-number combination:

<xsl:template match="doc">
  <xsl:for-each select="prog[generate-id() =
                             generate-id(key('progs',
                                             substring(., 3, 2))[1])]">
    <xsl:variable name="progs"
                  select="key('progs', substring(., 3, 2))" />
    ...
  </xsl:for-each>
</xsl:template>

Once you've got that set of $progs together, you can group them by
their position. Say you set a global parameter to the number you want
in each group:

<xsl:param name="nprogs" select="4" />

then you can loop through the $progs and use position() mod $nprogs to
work out whether you need to add a newline or a space before the value
of the particular prog:

<xsl:template match="doc">
  <xsl:for-each select="prog[generate-id() =
                             generate-id(key('progs',
                                             substring(., 3, 2))[1])]">
    <xsl:variable name="progs"
                  select="key('progs', substring(., 3, 2))" />
    <xsl:for-each select="$progs">
      <xsl:choose>
        <xsl:when test="position() mod $nprogs = 1">
          <xsl:text>&#xA;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text> </xsl:text>
        </xsl:otherwise>
      </xsl:choose>
      <xsl:value-of select="." />
    </xsl:for-each>
  </xsl:for-each>
</xsl:template>

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.