Subject: Re: [xsl] Emulating XPATH2 range in XSLT 1.0 From: Dimitre Novatchev <dnovatchev@xxxxxxxxx> Date: Wed, 29 Jul 2009 07:04:50 -0700 |
On Wed, Jul 29, 2009 at 6:51 AM, Hermann Stamm-Wilbrandt<STAMMW@xxxxxxxxxx> wrote: > >> You are discovering the "iter" function/template of FXSL 1.x, which >> has been available for 7+ years :) B : > > So "iter" corresponds to template named "loop". > > > "rannge:to" from below post does need very little overhead in > writing over the XSLT2 statement "for $f in 1 to 10000 ...". > For small iteration count (<10000) I would prefer it over "loop". > > Does FXSL provide an equivalent to "range:to" ? generateFromTo.xsl from my previous post. The template name is "generateBatch". > B B B B B B Dimitre Novatchev > > > > > > > > You are discovering the "iter" function/template of FXSL 1.x, which > has been available for 7+ years :) B : > > Here is the file generateFromTo.xsl from Fxsl 1.x : > > <xsl:stylesheet version="1.0" > B xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > B xmlns:ext="http://exslt.org/common" > B xmlns:f="http://fxsl.sf.net/" > B xmlns:myIncrement="f:myIncrement" > B exclude-result-prefixes="ext f myIncrement" > B > > > B <xsl:import href="iter.xsl"/> > B <!-- To be applied on any xml file --> > > B <xsl:output omit-xml-declaration="yes" indent="yes"/> > > B <xsl:template match="/"> > B B <xsl:call-template name="generateBatch"> > B B B <xsl:with-param name="pFrom" select="3"/> > B B B <xsl:with-param name="pTo" select="300"/> > B B </xsl:call-template> > B </xsl:template> > > B <myIncrement:myIncrement/> > > B <xsl:template name="generateBatch"> > B B <xsl:param name="pFrom"/> > B B <xsl:param name="pTo"/> > > B B <xsl:variable name="vFunIncr" > B B B B select="document('')/*/myIncrement:*[1]"/> > > B B <xsl:variable name="vResult"> > B B B <xsl:call-template name="scanIter"> > B B B B <xsl:with-param name="arg1" select="$pTo - $pFrom + 1"/> > B B B B <xsl:with-param name="arg2" select="$vFunIncr"/> > B B B B <xsl:with-param name="arg3" select="$pFrom - 1"/> > B B B B <xsl:with-param name="arg4" select="'obj'"/> > B B B </xsl:call-template> > B B </xsl:variable> > > B B <xsl:copy-of select="ext:node-set($vResult)/*[position() > 1]"/> > B </xsl:template> > > B <xsl:template match="myIncrement:*" mode="f:FXSL"> > B B <xsl:param name="arg1"/> > B B B <childnode> > B B B <xsl:value-of select="$arg1 + 1"/> > B B B </childnode> > B </xsl:template> > > </xsl:stylesheet> > > > When applied on any XML file (ignored), it produces the wanted (long > to be included) result. > > The above was written at the time with demonstration purposes and uses > simple recursion. > > I will provide a DVC-style of the same transformation, which has no > problems with recursion stack overflow for big and practical values of > $pTo - $pFrom. > > > -- > Cheers, > Dimitre Novatchev > --------------------------------------- > Truly great madness cannot be achieved without significant intelligence. > --------------------------------------- > To invent, you need a good imagination and a pile of junk > ------------------------------------- > Never fight an inanimate object > ------------------------------------- > You've achieved success in your field when you don't know whether what > you're doing is work or play > > > > > On Wed, Jul 29, 2009 at 3:37 AM, Hermann > Stamm-Wilbrandt<STAMMW@xxxxxxxxxx> wrote: >> >> Emulating the XSLT2 statement >> B B for $f in 1 to 10000 >> B B B ... >> >> may be done in XSLT1 (providing similar scoping of variable $f) by: >> B B <xsl:for-each select="range:to(1,10000)"> >> B B B <xsl:variable name="f" select="."/> >> B B B ... >> B B </xsl:for-each> >> >> In this case the complete set of numbers is generated into memory.: >> For bigger iteration count ("1 to 1000000" in T2.xsl) this >> may cause problems for the XSLT processor. >> >> Therefore "loop.xsl" may be used (T2.xsl, T3.xsl) to just iterate and >> do not generate all the numbers into memory. In order to allow for >> different bodies of the loops a template with name "loop" is called. >> Different implementations (body2.xsl, body3.xsl) are included >> together with "loop.xsl" into different stylesheets (T2.xsl, T3.xsl). >> >> >> I teststed this successfully with the following XSLT 1.0 processors:. >> - xsltproc (Using libxml 20626, libxslt 10117 and libexslt 813) >> - xalan-j (2.7.1) >> - IBM Websphere DataPower compiler >> >> >> All files may be downloaded here: >> http://www.stamm-wilbrandt.de/en/xsl-list/range/files.zip >> >> Find an example execution for T3.xsl at the bottom. >> >> $ cat range.xsl >> <xsl:stylesheet version="1.0" >> B xmlns:xsl B = "http://www.w3.org/1999/XSL/Transform" >> B xmlns:exslt = "http://exslt.org/common" >> B xmlns:func B = "http://exslt.org/functions" >> B xmlns:range = "urn:xpath1range" >> B extension-element-prefixes="func"> >> >> B <func:function name="range:to"> >> B B <xsl:param name="a"/> >> B B <xsl:param name="b"/> >> >> B B <func:result select="exslt:node-set(range:TO($a,$b))/*/text()"/>. >> B </func:function> >> >> B <func:function name="range:TO"> >> B B <xsl:param name="a"/> >> B B <xsl:param name="b"/> >> >> B B <xsl:choose> >> B B B <xsl:when test="$a > $b"/>> >> B B B <xsl:when test="$a = $b">>> >> B B B B <func:result> >> B B B B B <e><xsl:value-of select="$a"/></e> >> B B B B </func:result> >> B B B </xsl:when> >> B B B <xsl:otherwise>> >> B B B B <xsl:variable name="m" select="$a + floor(($b - $a) div 2)"/> >> B B B B <func:result> >> B B B B B <xsl:copy-of select="range:TO($a,$m)"/> >> B B B B B <xsl:copy-of select="range:TO($m+1,$b)"/> >> B B B B </func:result> >> B B B </xsl:otherwise> >> B B </xsl:choose> >> B </func:function> >> >> </xsl:stylesheet>> >> >> $ cat loop.xsl >> <xsl:stylesheet version="1.0" >> B xmlns:xsl=">http://www.w3.org/1999/XSL/Transform"> >> >> B <xsl:template name="loop"> >> B B <xsl:param name="from"/> >> B B <xsl:param name="to"/> >> >> B B <xsl:choose> >> B B B <xsl:when test="$from > $to"/> >> B B B <xsl:when test="$from = $to"> >> B B B B <xsl:call-template name="body"> >> B B B B B <xsl:with-param name="iter" select="$from"/> >> B B B B </xsl:call-template> >> B B B </xsl:when> >> B B B <xsl:otherwise> >> B B B B <xsl:variable name="middle" >> B B B B B B B B B B B select="$from + floor(($to - $from) div 2)"/> >> >> B B B B <xsl:call-template name="loop"> >> B B B B B <xsl:with-param name="from" select="$from" /> >> B B B B B <xsl:with-param name="to" select="$middle" /> >> B B B B </xsl:call-template> >> B B B B <xsl:call-template name="loop"> >> B B B B B <xsl:with-param name="from" select="$middle+1" /> >> B B B B B <xsl:with-param name="to" select="$to" /> >> B B B B </xsl:call-template> >> B B B </xsl:otherwise> >> B B </xsl:choose> >> B </xsl:template> >> >> </xsl:stylesheet> >> >> $ cat T1.xsl >> <xsl:stylesheet version="1.0" >> B xmlns:xsl B = "http://www.w3.org/1999/XSL/Transform" >> B xmlns:range = "urn:xpath1range"> >> >> B <xsl:include href="range.xsl"/>> >> >> B <xsl:template match="/">. >> B <!--: >> B B for $f in 1 to 10000 >> B B B ... >> >> B B emulated by: >> > <xsl:for-each select="range:to(1,10000)"> >> B B B <xsl:variable name="f" > select="."/> >> B B B ... >> B B </xsl:for-each> >> B --> >> B B <xsl:for-each select="range:to(1,10000)"> >> B B B <xsl:variable name="f" select="."/> >> >> B B B <xsl:value-of select="$f"/> >> B B </xsl:for-each> >> B </xsl:template> >> >> </xsl:stylesheet> >> >> $ cat T2.xsl >> <xsl:stylesheet version="1.0" >> B xmlns:xsl="http://www.w3.org/1999/XSL/Transform>"> >> >> B <xsl:output method="text"/> >> >> B <xsl:include href="loop.xsl"/> >> B <xsl:include href="body2.xsl"/> >> >> B <xsl:template match="/">. >> B B <xsl:call-template name="loop"> >> B B B <xsl:with-param name="from" select="1" /> >> B B B <xsl:with-param name="to" select="1000000" /> >> B B </xsl:call-template> >> B </xsl:template> >> >> </xsl:stylesheet> >> $ cat body2.xsl >> <xsl:stylesheet version="1.0" >> B xmlns:xsl="http://www.w3.org/1999/XSL/Transform>"> >> >> B <xsl:template name="body"> >> B B <xsl:param name="iter"/> >> B B <xsl:value-of select="$iter"/> >> B </xsl:template> >> </xsl:stylesheet> >> >> $ cat T3.xsl >> <xsl:stylesheet version="1.0" >> B xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> >> B <xsl:output method="xml" /> >> >> B <xsl:include href="loop.xsl"/> >> B <xsl:include href="body3.xsl"/> >> >> B <xsl:template match="/">. >> B B <file> >> B B B <xsl:call-template name="loop"> >> B B B B <xsl:with-param name="from" select="data/loop/@from" />) >> B B B B <xsl:with-param name="to" select="data/loop/@to" /> >> B B B </xsl:call-template> >> B B </file> >> B </xsl:template> >> >> </xsl:stylesheet> >> $ cat body3.xsl >> <xsl:stylesheet version="1.0" >> B xmlns:xsl="http://www.w3.org/1999/XSL/Transform>"> >> >> B <xsl:template name="body"> >> B B <xsl:param name="iter"/> >> B B <data> >> B B B <no><xsl:value-of select="$iter"/></no> >> B B B <sqr><xsl:value-of select="$iter*$iter"/></sqr> >> B B B <name><xsl:value-of select="data/pers/lname" />, <xsl:value-of >> select="data/pers/fname" /></name> >> B B </data>> >> B </xsl:template> >> </xsl:stylesheet> >> $ cat data.xml >> <data> >> B <loop from="3" to="5"/> >> B <pers> >> B B <lname>Smith</lname>> >> B B <fname>John</fname>>> >> B </pers> >> </data> >> >> $ xsltproc T3.xsl data.xml | tidy -q -xml >> <?xml version="1.0"?> >> <file> >> B <data> >> B B <no>3</no> >> B B <sqr>9</sqr>. >> B B <name>Smith, John</name> >> B </data>> >> B <data>>> >> B B <no>4</no> >> B B <sqr>16</sqr> >> B B <name>Smith, John</name> >> B </data>> >> B <data>>> >> B B <no>5</no> >> B B <sqr>25</sqr> >> B B <name>Smith, John</name> >> B </data>> >> </file> >> >> $ >> >> >> Mit besten GrC<Cen / Best wishes, >> >> Hermann Stamm-Wilbrandt >> Developer, XML Compiler >> WebSphere DataPower SOA Appliances >> ---------------------------------------------------------------------- >> IBM Deutschland Research & Development GmbH >> Vorsitzender des Aufsichtsrats: Martin Jetter >> GeschC$ftsfC<hrung: Erich Baier >> Sitz der Gesellschaft: BC6blingen >> Registergericht: Amtsgericht Stuttgart, HRB 243294 > > -- Cheers, Dimitre Novatchev --------------------------------------- Truly great madness cannot be achieved without significant intelligence. --------------------------------------- To invent, you need a good imagination and a pile of junk ------------------------------------- Never fight an inanimate object ------------------------------------- You've achieved success in your field when you don't know whether what you're doing is work or play
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Emulating XPATH2 range in, Hermann Stamm-Wilbra | Thread | Re: [xsl] Emulating XPATH2 range in, Hermann Stamm-Wilbra |
Re: [xsl] Emulating XPATH2 range in, Hermann Stamm-Wilbra | Date | Re: [xsl] Emulating XPATH2 range in, Hermann Stamm-Wilbra |
Month |