[xsl] Seeking an elegant XSLT function to check that a pair of numeric ranges are consecutive

Subject: [xsl] Seeking an elegant XSLT function to check that a pair of numeric ranges are consecutive
From: "Roger L Costello costello@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Sat, 25 May 2024 15:51:24 -0000
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