Re: [xsl] collapsing number ranges

Subject: Re: [xsl] collapsing number ranges
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Sun, 29 Aug 2004 10:55:31 +0100
Hi Bruce,

> So the tricky examples are what the algorithm describes in English as
>
> 1)   numbers that begin with a multiple of 100 do not get collapsed

  <xsl:choose>
    <xsl:when test="$begin gt 100 and $begin mod 100">
      ...
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$end" />
    </xsl:otherwise>
  </xsl:choose>

$begin mod 100 gives you the remainder after division by 100. When
tested as a boolean, $begin mod 100 is true if there's any remainder
and false if there isn't (i.e. if $begin is a multiple of 100). You
could use the test:

  $begin mod 100 neq 0

if that would make things clearer for you.
  
> 2)  "110 through 199, 210 through 299, etc.", where one uses "two or
> more digits as needed" for the end part of the range.
> 3)  "if three digits change in a four-digit number, use all four."

These are actually the same rule:

  <xsl:choose>
    <xsl:when test="$begin idiv 100 eq $end idiv 100">
      <xsl:value-of select="$end mod 100" />
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$end" />
    </xsl:otherwise>
  </xsl:choose>

$begin idiv 100 gives you all but the last two digits of $begin. $end
mod 100 gives you the last two digits of $end.

You could do this all with string manipulation instead (using the
substring() function to get the digits from the number), but you'd
have to make sure you dealt with getting 101-8 rather than 101-08.

Since both the <xsl:otherwise>s give you the same thing, you can
collapse them together as follows:

  <xsl:choose>
    <xsl:when test="$begin gt 100 and $begin mod 100 and
                    $begin idiv 100 eq $end idiv 100">
      <xsl:value-of select="$end mod 100" />
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$end" />
    </xsl:otherwise>
  </xsl:choose>

And of course you could use an if statement in an XPath, as in:

  <xsl:sequence select="if ($begin gt 100 and $begin mod 100 and
                            $begin idiv 100 eq $end idiv 100)
                        then $end mod 100
                        else $end" />

Cheers,

Jeni

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

Current Thread