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

Re: Reformatting

Subject: Re: Reformatting
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Fri, 11 May 2001 08:17:08 +0100
xsl if test next last
Hi Greg,

> I am trying to use XSLT format the output abbreviating ranges of
> channels. The above would ideally be formatted as:
>
>       1-4,10-13,24

This is a grouping problem.  Since it's all in sorted order already,
then you could just use a flat method where you apply templates to
everything and work out from each ch element what you should output.
Dan's already shown you a version of that method, although it could be
simplified to:

<xsl:template match="ch">
   <xsl:variable name="prev" select="preceding-sibling::*[1]"/>
   <xsl:variable name="next" select="following-sibling::*[1]"/>
   <xsl:choose>
      <!-- if next is not in sequence (end of group)... -->
      <xsl:when test=". != $next - 1">
         <!-- ...if part of sequence, add a '-' -->
         <xsl:if test=". = $prev + 1">-</xsl:if>
         <!-- ...give the value of the ch -->
         <xsl:value-of select="." />
         <!-- ...add a comma if there's a following ch -->
         <xsl:if test="$next">, </xsl:if>
      </xsl:when>
      <!-- if prev is not in sequence (start of group)... -->
      <xsl:when test=". != $prev + 1">
         <!-- ...give the value of the ch -->
         <xsl:value-of select="." />
      </xsl:when>
   </xsl:choose>
</xsl:template>

You could also use a grouping method where you only apply templates to
the first node in each group.  You can work out whether they're the
first node in the group by looking at whether they have a preceding
sibling whose value is one less than theirs:

<xsl:template match="T1">
   <xsl:apply-templates select="ch[. != preceding-sibling::*[1] + 1]" />
</xsl:template>

The ch-matching template will only be applied to nodes that are the
first in the group.  You can work out the last of that group by
finding the next following sibling whose first following sibling is
not one more than it is:

<xsl:template match="ch">
   <xsl:value-of select="." />
   <xsl:variable name="next"
                 select="following-sibling::*
                            [. != following-sibling::*[1] - 1][1]" />
   <xsl:if test="$next">
      <xsl:text />-<xsl:value-of select="$next" />
   </xsl:if>
   <xsl:if test="position() != last()">, </xsl:if>
</xsl:template>

I hope that helps,

Jeni

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



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


Current Thread
  • Reformatting
    • Brucato, Greg - Thu, 10 May 2001 19:03:37 -0400 (EDT)
      • Michael Kay - Fri, 11 May 2001 03:46:19 -0400 (EDT)
      • Jeni Tennison - Fri, 11 May 2001 04:34:13 -0400 (EDT) <=
      • <Possible follow-ups>
      • Dan Diebolt - Fri, 11 May 2001 00:10:30 -0400 (EDT)

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.