[xsl] Re: Re: Re: Assignment no, dynamic scoping si (was: Re: RE: Wishes for XSLrevisions ...

Subject: [xsl] Re: Re: Re: Assignment no, dynamic scoping si (was: Re: RE: Wishes for XSLrevisions ...
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Fri, 4 Jan 2002 00:25:35 -0800 (PST)
 terje at in-progress dot com (Terje Norderhaug) wrote:
> 
> At 6:49 PM 1/2/02, Dimitre Novatchev wrote:
> >Gunther Schadow <gunther at aurora dot regenstrief dot org> wrote:
> >
> >> So, in a world with dynamic scoping / implicit parameters,
> >> lowlyweb.org would do this:
> >> 
> >> <xsl:stylesheet id='urn:lowlyweb.org:onlinebook'>
> >> 
> >> <xsl:import href='http://bigbucksbooks.com/onlinebook.xsl'/>
> >> 
> >> <xsl:template match='section'>
> >>    ...
> >>    <xsl:apply-templates>
> >>      <xsl:with-implicit-param name='source' select='@source'/>
> >>    </xsl:apply-templates>
> >>    ...
> >> </xsl:template>
> >> 
> >> <xsl:template match='paragraph'>
> >>    <xsl:implicit-param name='source' select='@source'/>
> >>    <p class='$source'>
> >>      <xsl:apply-templates/>
> >>    </p>
> >> </xsl:template>
> >> 
> >> </xsl:stylesheet>
> >> 
> >> This template would only touch the section and paragraph elements
> >> of bigbucksbooks and would leave everything else untouched.
> >> The implicit parameter source is bound to the @source value given
> >> in the document for everything nested within that section. Now,
> >> most of this stuff doesn't care, until we get down to the paragraph
> >> element that now has this implicit parameter available no matter
> >> how many things were passed through.
> >> 
> >> I cannot see how to do that with global variables as you suggest,
> >> because that book contains many sections and needs to switch
> >> between the different sources all the time per each section.
> >> 
> >> I can see how one can do the same thing with explicit parameters,
> >> which however, requires modifying all of bigbucksbooks templates
> >> for table, list (and then: frame, box, float, imagetitle,
> >> rotated-text, ...).
> >> 
> >> So, if you could show me how this can be done without changing the
> >> whole thing, I am all ears.
> >
> >Certainly. This is very simple using XSLT. You even don't have to modify the
> >"section" template neither do you need a global variable. In the "paragraph"
> >template declare and use the following local variable:
> >
> ><xsl:variable name="source" select="ancestor::section[1]/@source"/>
> 
> 1. This assumes that you know certain constraints about the document, such as that
> a
> section never contains a section. Without  this constraint, a template such as
> below
> in the imported document would make your work-around unreliable as
> ancestor::section[1] might give the wrong element in the paragraph template:
> 
> <xsl:template match='section//section'>
>    <xsl:apply-templates/>
> </xsl:template>

Yes, using implicit parameters without knowing the exact structure of the document
is literally meaningless, as your example proves it:

In case a paragraph was contained in two "section"s, then the settings for the
implicit parameter "source" in the outer "section" are overlayed/shadowed by those
in the innermost (closest) "section" containing the paragraph.

So, while ancestor::section[1] will still access the current value of the implicit
parameter "source", all previous values set by outer "section"s would be lost. What
is the meaning of not knowing which parameters will actually reach the recepient?

Clearly this is confusing at best and a debugging nightmare. As David Carlisle very
well explained, this will result if "dynamic scoping" is artificially supplanted
into XSLT. Artificially, because the programming model supported by XSLT (control by
matching input as opposed to control by call) is very, very different from a
programming model in which dynamic scoping might be more appropriate.

> 
> 2. The work-around may fail if any xsl:apply-templates instructions in the
> imported
> stylesheet selects nodes outside the descendants of the 'section' element. If so,
> you have no guarantee that ancestor::section[1] will give you the section element
> that was the current node for a 'section' template earlier in the call chain.
> 

This contradicts the concrete example given -- if the current node was changed by
some template, so that as a result the reached "paragraph" no longer belonged to the
same "section", then the value of the implicit parameter will be processed as
specified by the original "section"-matching template and will produce a false
result -- the "paragraph", which does not belong to the "section" that specified its
"source" will be rendered using the colour matching that section's source.

This shows once again that using implicit parameters would be unreliable in cases
like the one you describe.


> 3. If the 'section' template contains two xsl:apply-templates where each pass on a
> different value for the dynamic variable $source (or another template binds the
> variable) the 'paragraph' template might be instantiated with different values for
> $source. The same value might be impossible to calculate from the current context
> in
> the 'paragraph' template, e.g.:
> 
> <xsl:template match='section'>
>     <xsl:apply-templates>
>       <xsl:with-implicit-param name='source' select='@source'/>
>     </xsl:apply-templates>
>     <xsl:apply-templates>
>       <xsl:with-implicit-param name='source' select='"default"'/>
>     </xsl:apply-templates>
>  </xsl:template>  
> 

This seems to be the first example from four or five in a row, that may show some
value of using implicit parameters. 

Once again, this demonstrates an attempt to mix two utterly different programming
models. xsl:apply-templates is not at all similar to xsl:call-templates. 

I cannot better than David Carlisle explain the consequences of mixing the two
programming models:

"Unlike some other more traditional languages, in XSLT the calling order
of the templates is not at all explict in the program source and is
driven by whatever document is passed in as data.  This means that
normally templates need to be written to work wherever they happen to
match and _without_ regard to the particular calling sequence that
caused them to fire. Dynamic scope would radically change that and mean
that the behaviour of a template would much more directly depend on the
stack of "currently active" templates. It is not at all clear to me that
this would make XSLT an easier language to understand or work with.
At present any dependency on previously called templates is (a) rare and
(b) explictly flagged by the declaration and passing or parameters.
This is a good thing (I believe) Of course the fact that the syntax for
passing parameters is so verbose (even by XSL standards) means that it
is sometimes a pain, but there have been some "syntactic sugar"
proposals to help with that without changing the underlying execution
model".

> 4. Replicating the same xpath expression in each template that want to use the
> $source isn't exactly good practive with respect to writing maintainable code. 

 The code will be more maintainable, if it is exactly known what nodeset/value is
being accessed than having to guess exactly which of the possibly many overlaying
definitions of an implicit parameter successfully made it through.

> Nor
> does it facilitate efficient execution. 
> 

This is not obvious at all. The time to evaluate an XPath expression is the same
regardless whether the evaluation was done by the caller or the callee. In fact the
necessity to maintain the stack (push and pop from it, and also the increased memory
it requires) will probably make passing implicit parameters less efficient.


> In conclusion, dynamic variables provide a general solution to problems that
> work-arounds only can solve in special cases with great dependency on document
> constraints and assumptions about the imported stylesheet. 
> 

As I hope the reasoning above have made quite clear, there isn't good justification
for such conclusions in the case of pushing forward for dynamic variables in XSLT.

Cheers,
Dimitre Novatchev.

__________________________________________________
Do You Yahoo!?
Send your FREE holiday greetings online!
http://greetings.yahoo.com

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread