Subject: Re: [xsl] XSLT 2.0 function - fastest node comparison From: Dimitre Novatchev <dnovatchev@xxxxxxxxx> Date: Fri, 11 Mar 2005 20:38:13 +1100 |
On Thu, 10 Mar 2005 15:09:24 -0000, Michael Kay <mike@xxxxxxxxxxxx> wrote: > If there are many ranges and you need it to go at better than linear speed, > you could code a binary-chop. I think Dimitre has done this in the past, I > don't know if it's available in packaged form. Here are two XSLT 2.0 solutions: a DVC (Divide and Conquer) and BS (Binary Search): <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:f="http://fxsl.sf.net/" xmlns:t="http://fxsl.sf.net/test" exclude-result-prefixes="f xs t" > <xsl:output method="text"/> <xsl:variable name="vRanges" as="element()+"> <range from="988" to="989"/> <range from="1008" to="1009"/> <range from="1014" to="1014"/> <range from="1025" to="1036"/> <range from="1038" to="1103"/> <range from="1105" to="1116"/> <range from="1118" to="1119"/> <range from="4150" to="4150"/> <range from="8194" to="8197"/> </xsl:variable> <xsl:template match="/"> <xsl:value-of select="t:inRangeDVC($vRanges, 8195)"/>, <xsl:text/> <xsl:value-of select="t:inRangeBS($vRanges, 8195, 1, count($vRanges))"/> </xsl:template> <xsl:function name="t:inRangeDVC" as="xs:boolean"> <xsl:param name="pRanges" as="element()*"/> <xsl:param name="pVal"/> <xsl:sequence select= "if(empty($pRanges)) then false() else for $cnt in count($pRanges) return if($cnt = 1) then $pVal ge xs:integer($pRanges[1]/@from) and $pVal le xs:integer($pRanges[1]/@to) else for $vHalf in $cnt idiv 2 return if(t:inRangeDVC($pRanges[position() le $vHalf], $pVal)) then true() else t:inRangeDVC($pRanges[position() gt $vHalf], $pVal) " /> </xsl:function> <xsl:function name="t:inRangeBS" as="xs:boolean"> <xsl:param name="pRanges" as="element()*"/> <xsl:param name="pVal"/> <xsl:param name="pLow" as="xs:integer"/> <xsl:param name="pUp" as="xs:integer"/> <xsl:sequence select= "if($pLow gt $pUp) then false() else for $mid in ($pLow + $pUp) idiv 2, $v in $pRanges[$mid] return if($pVal ge xs:integer($v/@from) and $pVal le xs:integer($v/@to)) then true() else if($pVal lt xs:integer($v/@from)) then t:inRangeBS($pRanges, $pVal, $pLow, $mid - 1) else t:inRangeBS($pRanges, $pVal, $mid+1, $pUp) "/> </xsl:function> </xsl:stylesheet> Cheers, Dimitre Novatchev
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] XSLT 2.0 function - faste, Michael Kay | Thread | RE: [xsl] XSLT 2.0 function - faste, Kirkham, Pete (UK) |
RE: [xsl] Variables and HTML, Michael Kay | Date | Re: [xsl] Variables and HTML, David Carlisle |
Month |