[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Emulating XPATH2 range in XSLT 1.0


Subject: Re: [xsl] Emulating XPATH2 range in XSLT 1.0
From: Hermann Stamm-Wilbrandt <STAMMW@xxxxxxxxxx>
Date: Wed, 29 Jul 2009 21:59:33 +0200

> > Does FXSL provide an equivalent to "range:to" ?
>
>
> generateFromTo.xsl from my previous post.
>
> The template name is "generateBatch".

I created file "fxsl-range.xsl" from "generateFromTo.xsl" and
tried (unsuccessfully) to transform template "generateBatch"
into "func:function" with name "range:to".

This would allow to include "fxsl-range.xsl" into "T0.xsl"
and see below working based on fxsl iter concept:

    <xsl:for-each select="range:to(1,10000)">
      <xsl:variable name="f" select="."/>
      ...
    </xsl:for-each>

May you please show how to create function "range:to" in:
fxsl-range.xsl as described above?


Mit besten Gr|_en / Best wishes,

Hermann Stamm-Wilbrandt
Developer, XML Compiler
WebSphere DataPower SOA Appliances
----------------------------------------------------------------------
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschdftsf|hrung: Erich Baier
Sitz der Gesellschaft: Bvblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294



             Dimitre Novatchev
             <dnovatchev@gmail
             .com>                                                      To
                                       xsl-list@xxxxxxxxxxxxxxxxxxxxxx
             07/29/2009 04:04                                           cc
             PM
                                                                   Subject
                                       Re: [xsl] Emulating XPATH2 range in
             Please respond to         XSLT 1.0
             xsl-list@xxxxxxxx
              lberrytech.com








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 :)  :
>
> 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".






>             Dimitre Novatchev





>
>
>
>
>
>
>
> You are discovering the "iter" function/template of FXSL 1.x, which
> has been available for 7+ years :)  :
>
> Here is the file generateFromTo.xsl from Fxsl 1.x :
>
> <xsl:stylesheet version="1.0"
>  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>  xmlns:ext="http://exslt.org/common"
>  xmlns:f="http://fxsl.sf.net/"
>  xmlns:myIncrement="f:myIncrement"
>  exclude-result-prefixes="ext f myIncrement"
>  >
>
>  <xsl:import href="iter.xsl"/>
>  <!-- To be applied on any xml file -->
>
>  <xsl:output omit-xml-declaration="yes" indent="yes"/>
>
>  <xsl:template match="/">
>    <xsl:call-template name="generateBatch">
>      <xsl:with-param name="pFrom" select="3"/>
>      <xsl:with-param name="pTo" select="300"/>
>    </xsl:call-template>
>  </xsl:template>
>
>  <myIncrement:myIncrement/>
>
>  <xsl:template name="generateBatch">
>    <xsl:param name="pFrom"/>
>    <xsl:param name="pTo"/>
>
>    <xsl:variable name="vFunIncr"
>         select="document('')/*/myIncrement:*[1]"/>
>
>    <xsl:variable name="vResult">
>      <xsl:call-template name="scanIter">
>        <xsl:with-param name="arg1" select="$pTo - $pFrom + 1"/>
>        <xsl:with-param name="arg2" select="$vFunIncr"/>
>        <xsl:with-param name="arg3" select="$pFrom - 1"/>
>        <xsl:with-param name="arg4" select="'obj'"/>
>      </xsl:call-template>
>    </xsl:variable>
>
>    <xsl:copy-of select="ext:node-set($vResult)/*[position() > 1]"/>
>   </xsl:template>
>
>   <xsl:template match="myIncrement:*" mode="f:FXSL">
>     <xsl:param name="arg1"/>
>       <childnode>
>       <xsl:value-of select="$arg1 + 1"/>
>       </childnode>
>   </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
>>    for $f in 1 to 10000
>>      ...
>>
>> may be done in XSLT1 (providing similar scoping of variable $f) by:
>>    <xsl:for-each select="range:to(1,10000)">
>>      <xsl:variable name="f" select="."/>
>>      ...
>>    </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"
>>  xmlns:xsl   = "http://www.w3.org/1999/XSL/Transform"
>>  xmlns:exslt = "http://exslt.org/common"
>>  xmlns:func  = "http://exslt.org/functions"
>>  xmlns:range = "urn:xpath1range"
>>  extension-element-prefixes="func">
>>
>>  <func:function name="range:to">
>>    <xsl:param name="a"/>
>>    <xsl:param name="b"/>
>>
>>    <func:result select="exslt:node-set(range:TO($a,$b))/*/text()"/>.
>>  </func:function>
>>
>>  <func:function name="range:TO">
>>    <xsl:param name="a"/>
>>    <xsl:param name="b"/>
>>
>>    <xsl:choose>
>>      <xsl:when test="$a > $b"/>>
>>      <xsl:when test="$a = $b">>>
>>        <func:result>
>>          <e><xsl:value-of select="$a"/></e>
>>        </func:result>
>>      </xsl:when>
>>      <xsl:otherwise>>
>>        <xsl:variable name="m" select="$a + floor(($b - $a) div 2)"/>
>>        <func:result>
>>          <xsl:copy-of select="range:TO($a,$m)"/>
>>          <xsl:copy-of select="range:TO($m+1,$b)"/>
>>        </func:result>
>>      </xsl:otherwise>
>>    </xsl:choose>
>>  </func:function>
>>
>> </xsl:stylesheet>>
>>
>> $ cat loop.xsl
>> <xsl:stylesheet version="1.0"
>>  xmlns:xsl=">>http://www.w3.org/1999/XSL/Transform">
>>
>>  <xsl:template name="loop">
>>    <xsl:param name="from"/>
>>    <xsl:param name="to"/>
>>
>>    <xsl:choose>
>>      <xsl:when test="$from &gt; $to"/>
>>      <xsl:when test="$from = $to">
>>        <xsl:call-template name="body">
>>          <xsl:with-param name="iter" select="$from"/>
>>        </xsl:call-template>
>>      </xsl:when>
>>      <xsl:otherwise>
>>        <xsl:variable name="middle"
>>                      select="$from + floor(($to - $from) div 2)"/>
>>
>>        <xsl:call-template name="loop">
>>          <xsl:with-param name="from" select="$from" />
>>          <xsl:with-param name="to" select="$middle" />
>>        </xsl:call-template>
>>        <xsl:call-template name="loop">
>>          <xsl:with-param name="from" select="$middle+1" />
>>          <xsl:with-param name="to" select="$to" />
>>        </xsl:call-template>
>>      </xsl:otherwise>
>>    </xsl:choose>
>>  </xsl:template>
>>
>> </xsl:stylesheet>
>>
>> $ cat T1.xsl
>> <xsl:stylesheet version="1.0"
>>  xmlns:xsl   = "http://www.w3.org/1999/XSL/Transform"
>>  xmlns:range = "urn:xpath1range">
>>
>>  <xsl:include href="range.xsl"/>>
>>
>>  <xsl:template match="/">.
>>  <!--:
>>    for $f in 1 to 10000
>>      ...
>>
>>    emulated by:
>>
>
<xsl:for-each select="range:to(1,10000)">
>>      <xsl:variable name="f"
>
select="."/>
>>      ...
>>    </xsl:for-each>
>>  -->
>>    <xsl:for-each select="range:to(1,10000)">
>>      <xsl:variable name="f" select="."/>
>>
>>      <xsl:value-of select="$f"/>
>>    </xsl:for-each>
>>  </xsl:template>
>>
>> </xsl:stylesheet>
>>
>> $ cat T2.xsl
>> <xsl:stylesheet version="1.0"
>>  xmlns:xsl=">http://www.w3.org/1999/XSL/Transform>">
>>
>>  <xsl:output method="text"/>
>>
>>  <xsl:include href="loop.xsl"/>
>>  <xsl:include href="body2.xsl"/>
>>
>>  <xsl:template match="/">.
>>    <xsl:call-template name="loop">
>>      <xsl:with-param name="from" select="1" />
>>      <xsl:with-param name="to" select="1000000" />
>>    </xsl:call-template>
>>  </xsl:template>
>>
>> </xsl:stylesheet>
>> $ cat body2.xsl
>> <xsl:stylesheet version="1.0"
>>  xmlns:xsl="http://www.w3.org/1999/XSL/Transform>">
>>
>>  <xsl:template name="body">
>>    <xsl:param name="iter"/>
>>    <xsl:value-of select="$iter"/>
>>  </xsl:template>
>> </xsl:stylesheet>
>>
>> $ cat T3.xsl
>> <xsl:stylesheet version="1.0"
>>  xmlns:xsl="http://www.w3.org/1999/XSL/Transform>">
>>  <xsl:output method="xml" />
>>
>>  <xsl:include href="loop.xsl"/>
>>  <xsl:include href="body3.xsl"/>
>>
>>  <xsl:template match="/">.
>>    <file>
>>      <xsl:call-template name="loop">
>>        <xsl:with-param name="from" select="data/loop/@from" />)
>>        <xsl:with-param name="to" select="data/loop/@to" />
>>      </xsl:call-template>
>>    </file>
>>  </xsl:template>
>>
>> </xsl:stylesheet>
>> $ cat body3.xsl
>> <xsl:stylesheet version="1.0"
>>  xmlns:xsl="http://www.w3.org/1999/XSL/Transform>>">
>>
>>  <xsl:template name="body">
>>    <xsl:param name="iter"/>
>>    <data>
>>      <no><xsl:value-of select="$iter"/></no>
>>      <sqr><xsl:value-of select="$iter*$iter"/></sqr>
>>      <name><xsl:value-of select="data/pers/lname" />, <xsl:value-of
>> select="data/pers/fname" /></name>
>>    </data>>
>>  </xsl:template>
>> </xsl:stylesheet>
>> $ cat data.xml
>> <data>
>>  <loop from="3" to="5"/>
>>  <pers>
>>    <lname>Smith</lname>>
>>    <fname>John</fname>>>
>>  </pers>
>> </data>
>>
>> $ xsltproc T3.xsl data.xml | tidy -q -xml
>> <?xml version="1.0"?>
>> <file>
>>  <data>
>>    <no>3</no>
>>    <sqr>9</sqr>.
>>    <name>Smith, John</name>
>>  </data>>
>>  <data>>>
>>    <no>4</no>
>>    <sqr>16</sqr>
>>    <name>Smith, John</name>
>>  </data>>
>>  <data>>>
>>    <no>5</no>
>>    <sqr>25</sqr>
>>    <name>Smith, John</name>
>>  </data>>
>> </file>
>>
>> $
>>
>>
>> Mit besten Gr|_en / Best wishes,
>>
>> Hermann Stamm-Wilbrandt
>> Developer, XML Compiler
>> WebSphere DataPower SOA Appliances
>> ----------------------------------------------------------------------
>> IBM Deutschland Research & Development GmbH
>> Vorsitzender des Aufsichtsrats: Martin Jetter
>> Geschdftsf|hrung: Erich Baier
>> Sitz der Gesellschaft: Bvblingen
>> 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
Keywords