| 
 
Subject: Re: [xsl] Seeking an elegant XSLT function to check that a pair  of numeric ranges are consecutive From: "Dimitre Novatchev dnovatchev@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Sat, 25 May 2024 18:29:54 -0000  | 
Here is a pure XPath solution - 7 lines well-formatted expression:
let $ranges := /*/*/*,
    $starts := $ranges/xs:integer(substring-before(. || '-', '-')),
    $ends := $ranges/xs:integer(if(contains(., '-')) then
substring-after(., '-')
                                else .)
  return
    every $i in 1 to count($starts) -1 satisfies
      $ends[$i] eq $starts[$i +1] -1
Thanks,
Dimitre
On Sat, May 25, 2024 at 8:51b/AM Roger L Costello costello@xxxxxxxxx <
xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
> Hi Folks,
>
> I have an XML document that contains a series of records and each record
> contains a numeric range:
>
> <Document>
>     <Record>
>         <Range>0-2</Range>
>     </Record>
>     <Record>
>         <Range>3-7</Range>
>     </Record>
>     <Record>
>         <Range>8</Range>
>     </Record>
>     <Record>
>         <Range>9-15</Range>
>     </Record>
> </Document>
>
> Notice that a "range" is either two integers separated by a dash (e.g.,
> 0-2), or a single integer (e.g., 8).
>
> I need to check the ranges, to ensure that adjacent pairs contain ranges
> that are consecutive. Thus, this pair of ranges:
>
>     0-2, 3-7
>
> is good (i.e., consecutive), but this pair of ranges:
>
>     0-2, 5-8
>
> is bad (i.e., not consecutive).
>
> I wrote an XSLT function that checks a pair of ranges and returns true if
> they are consecutive and false if they are not consecutive.
>
> My function is okay. It seems to work properly. But it's kind of ugly and
> brute-force. I wonder if there is a more elegant solution?
>
> Here is my function:
>
> <xsl:function name="f:do-ranges-connect" as="xs:boolean">
>     <xsl:param name="previous-range"/>
>     <xsl:param name="current-range"/>
>     <xsl:choose>
>         <xsl:when test="matches($previous-range,'^[0-9]+$') and
> matches($current-range,'^[0-9]+$')">
>             <xsl:value-of select="xs:integer($current-range) eq
> xs:integer($previous-range) + 1"/>
>         </xsl:when>
>         <xsl:when test="matches($previous-range,'^[0-9]+$') and
> matches($current-range,'^[0-9]+-[0-9]+$')">
>             <xsl:variable name="start"
> select="substring-before($current-range,'-')"/>
>             <xsl:value-of select="xs:integer($start) eq
> xs:integer($previous-range) + 1"/>
>         </xsl:when>
>         <xsl:when test="matches($previous-range,'^[0-9]+-[0-9]+$') and
> matches($current-range,'^[0-9]+$')">
>             <xsl:variable name="end"
> select="substring-after($previous-range,'-')"/>
>             <xsl:value-of select="xs:integer($current-range) eq
> xs:integer($end) + 1"/>
>         </xsl:when>
>         <xsl:when test="matches($previous-range,'^[0-9]+-[0-9]+$') and
> matches($current-range,'^[0-9]+-[0-9]+$')">
>             <xsl:variable name="start"
> select="substring-before($current-range,'-')"/>
>             <xsl:variable name="end"
> select="substring-after($previous-range,'-')"/>
>             <xsl:value-of select="xs:integer($start) eq xs:integer($end) +
> 1"/>
>         </xsl:when>
>         <xsl:otherwise>
>             <xsl:message>The range strings are non-conformant</xsl:message>
>             <xsl:value-of select="false()"/>
>         </xsl:otherwise>
>     </xsl:choose>
> </xsl:function>
| Current Thread | 
|---|
  | 
| <- Previous | Index | Next -> | 
|---|---|---|
| Re: [xsl] Seeking an elegant XSLT f, David Carlisle d.p.c | Thread | Re: [xsl] Seeking an elegant XSLT f, Jeffrey Greif jgreif | 
| Re: [xsl] Re: Seeking an elegant XS, Wendell Piez wapiez@ | Date | Re: [xsl] Seeking an elegant XSLT f, Jeffrey Greif jgreif | 
| Month |