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 20:24:05 -0000 |
> My guess is that this is not the case with this problem, otherwise they would have chosen another range delimiter, for example "~". And in this case the expression becomes: 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 And one could, of course, parameterise further: let $ranges := /*/*/*, $d := '~', $starts := $ranges/xs:integer(substring-before(. || $d, $d)), $ends := $ranges/xs:integer(if(contains(., $d)) then substring-after(., $d) else .) return every $i in 1 to count($starts) -1 satisfies $ends[$i] eq $starts[$i +1] -1 On Sat, May 25, 2024 at 1:20b/PM Dimitre Novatchev dnovatchev@xxxxxxxxx < xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote: > > This XPath expression is lovely, but what if the start of the range is a > negative integer? > > My guess is that this is not the case with this problem, otherwise they > would have chosen another range delimiter, for example "~". > > Thanks, > Dimitre > > On Sat, May 25, 2024 at 1:13b/PM Jeffrey Greif jgreif@xxxxxxxxxxxxxxxxxxxx > <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote: > >> This XPath expression is lovely, but what if the start of the range is a >> negative integer? >> >> On Sat, May 25, 2024 at 11:30b/AM Dimitre Novatchev dnovatchev@xxxxxxxxx < >> xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote: >> >>> 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> >>>> >>>> >>>> >>> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list> >>> EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/1067740> (by >>> email) >>> >> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list> >> EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/782854> (by >> email) >> > > > XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list> > EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/782854> (by > email <>)
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Seeking an elegant XSLT f, Dimitre Novatchev dn | Thread | [xsl] Re: Seeking an elegant XSLT f, Roger L Costello cos |
Re: [xsl] Seeking an elegant XSLT f, Dimitre Novatchev dn | Date | [xsl] Re: Seeking an elegant XSLT f, Roger L Costello cos |
Month |