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 |