Groups | Blog | Home
all groups > dotnet xml > december 2003 >

dotnet xml : XSLT Param Scope?


Keith Chadwick
12/5/2003 8:15:46 PM
I have a fairly hefty XSLT file that for the sake of debugging and clarity I
wish to split into some separate sub-templates contained within the same
file. The master template calls an apply-templates and passes a node set to
it. This template in turn defines approximately 15 variables that dictate
how the following template should proceed. Pseudo example:

<!-- Root transformation called via .NET XSLTransform()-->
<xsl:template match="/">
.. do a bunch of stuff to render the html
<xsl:apply-template select="//object[@class='lineItem' and
@ffid='fees']" mode="LINEITEM"/>
...bunch more of html stuff
</xsl:template>

<xsl:template select="//object" mode="LINEITEM">
<!-- define a bunch of variables based on the current node that dictate
the detailed formatting of that node in html -->

<!-- choice 1 --->
do some formatting
<!-- or -->
<!-- choice 2 --->
do some other formatting
</xsl:template>

Now what I would like to do is move choice 1 and choice 2 into their own
templates and NOT have to redefine all of the 'formatting' variables. I
realize that a param defined at the stylesheet level is available in any
child template but, and it would seem natural, if within a template using a
call-template or apply-template would mean that the parents params are
available, nes-pas? Like in the old VB 6 days where you would have a public
variable to the application and a private variable defined in the
declarations of class, in other words, public to the class but not the
application. Is this possible or is my head stuck in object land far to
much :-)

Cheers
Keith

PS: If not possible it should be because it seems completely logical to me,
somebody write an extension!!! :-)



Keith Chadwick
12/6/2003 10:27:51 AM
I knew that would be your answer and still the same issue but twice as much.
Now I am defining them in the parent template, in the with-param for each
template I call.

I realize how it works and what I am stating is that the language lacks
elegance in this area. It would be nice to be able to say:

<xsl:param name="myvar" scope="[template][stylesheet]" value=""/>

A param defined outside of a template would automatically have a scope of
template but inside a template you could override it and state stylesheet
thereby making "available" to any template in the style sheet. I can think
of a lot implementations where it would be nice to have a document fragment
placed in the param based on the templates processing and then be available
to any other template in the transformation.

Cheers
Keith

[quoted text, click to view]

Keith Chadwick
12/6/2003 2:01:08 PM
Ok then what if I have 10 variables/params that ALL need to be passed to
each sub template?

The reason for this is that the user creates document definitions via a
wizard. The wizard offers up a bunch of options on how to format certain
sets of data. I could create a template for each possible combination of
options but there would be far to much duplicated code to manage. The
property 'style' which is loaded into a param dictates the overall layout
format. The other properties dictate some sub formatting, like place option
controls on right or left. So what I have is:

<xsl:template select="//object">
<xsl:param name="style" select="metrics/render/@style"/>

<!-- sub-formatting properties -->
<xsl:param name="controllayout" select="metrics/render/@controllayout"/>
... ten more params here that dictate the formatting style

<xsl:choose>
<xsl:when test="@style=1">
<xsl:call-template name="LINEITEM_GRID"/>
</xsl:when>
<xsl:when test="@style="2">
<xsl:call-template name="LINEITEM_BLOCK"/>
</xsl:when>
... more when test
</xsl:choose>
</xsl:template>


In the section sub-formatting properties there are currently 10 params and
there will be more as the wizard development progresses. Now since each
child template runs in the same node as caller I can simply move the
definition of each of the sub-formatting param into each of the
call-template templates. I know what the solution is, but my issue is that
in this particular circumstance I am duplicating each of those params or
variables in each child template. This in its self is not the issue and of
course works fine. My issue is that I end up with a fair amount of
duplicated code, approx 80 lines (10 params * 8 styles). I hate copying and
pasting code like that it lacks elegance and becomes inherently more
difficult to maintain. From my point of view a param defined in a template
should be automatically accessible to the template called within the that
template. Since the call-template runs in the context of the current node
why should it not also exist in the context of params or variable also
defined during that node iteration? Now I realize that in my above example
the values assigned to the params are available in each child template
because they belong to the same node set so perhaps this is not the best
example but do you get my drift?

I love the functionality of XSLT it solves a lot of problems that exist in
web developments but like any language I find it lacking in some regards.
But if we don't bring stuff like this up the language never grows. It is
like CSS, I have been asking for years for a RADIUS attribute on borders
allowing for rounded border corners.

Cheers
Keith

[quoted text, click to view]

Dimitre Novatchev
12/6/2003 2:49:01 PM
[quoted text, click to view]

Nothing is "available" by itself. The parameters/variables in a template
will be available to a called (or applied) template if you pass them as
parameters.

Read about the xsl:with-param and xsl:param pair of instructions.



=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL


Dimitre Novatchev
12/6/2003 7:22:27 PM

[quoted text, click to view]

This is perfectly possible to do without the constructs you propose above:

<xsl:variable name="vrtfVar">
<xsl:apply-templates/>
</xsl:variable>

<xsl:apply-templates select="someExpression">
<xsl:with-param name="somepName" select="msxsl:node-set($vrtfVar)/node"/>
</xsl:apply-templates>


The visibility rules for an xsl:param or xsl:variable are not different than
in most block-structured programming languages: an xsl:variable defined in
an outer block is visible after its definition in the same block or in any
nested blocks, following the definition of the variable (exactly the same
about xsl:param). An xsl:variable defined in an inner block is not visible
(and in fact does not exist) outside of that block.



=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL



Dimitre Novatchev
12/6/2003 8:54:23 PM
[quoted text, click to view]

If you have many parameters, you may combine them in *one* single parameter,
which would be (guess what?) a node-set.
This solves the code duplication issue completely.

Alternatively, one can construct a single global variable, that again will
contain a node-set with all needed parameter-values. Once constructed, this
global variable is accessible from everywhere and no parameter passing is
necessary.


[quoted text, click to view]

In this case this is not a big problem. In XSLT2.0 they would have the so
called "tunnel parameters" better known in the outside world as "implicit
parameters".

While this also solves your problem, it seems to me that there is rarely a
need for using this feature. That is, we couls always split a program block
into several pieces and pass the parameters only to the sub-function that
really needs them.

So for me this is not a problem (never has been a *big* or annoying
problem). Of course I have other tricks in my sleeve (e.g. something I call
"environments" -- see e.g.
http://sources.redhat.com/ml/xsl-list/2001-11/msg01096.html or
http://fxsl.sourceforge.net/articles/PartialApps/Partial%20Applications.html)
but I had never needed to use such "heavy armament" in real life tasks. I
used environments and they were very handy in my implementation of a Monad
Class -like computation in XSLT (to put it simply, you can "modify
variables" and explicitly order computations, have state,... etc.)... but
that's another story.


=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL




Kathleen Dollard
12/26/2003 11:03:18 AM
Keith,

Sorrry to be late, but I was perusing here looking for something else and
saw this.

I definitely agree with you that duplicating selection information is a bad
idea. I have not read this whole thread, so wondered if you had considered
using global variables for these values. I find these extremely useful.
While the idea of "global variables" has negative connotations in some
languages, in XSLT, this is more or less the same as a module level variable
and has all of the same benefits.

Kathleen

[quoted text, click to view]

Keith Chadwick
12/27/2003 12:44:00 PM
Yes in the end, I ended up using global parameter values that are passed by
the caller.

Although XSLT is extremely powerful I do find that at this stage of its
development it is lacking in areas that are common for other languages. I
believe and hope that over the next several years that many of these issues
will be addressed by the w3c organization. Until then there are always work
arounds but in XSLT it seems they always require a lot of extra typing!

Happy Holidays
Keith Chadwick

[quoted text, click to view]

Dimitre Novatchev
12/27/2003 9:34:31 PM

[quoted text, click to view]

Before making a strong statement as this one must be sure he really knows
the
language well.

XSLT is a functional language and this makes it very different indeed from
any imperative language. The fact that XSLT lacks some most typical
"features" of imperative languages is not a shortcoming but in fact a big
advantage.

[quoted text, click to view]

They would appreciate any feedback now, post your proposals at:

public-qt-comments@w3.org

In your particular case a feature of XSLT 2.0 called "tunnel parameters"
will most probably meet exactly your requirements -- although one can do
without it in most cases.

[quoted text, click to view]

The language is what some people will consider verbose by design, but it is
very compact compared to XQuery.

The "trouble" with XSLT for some people is that it requires *thinking* ...

If one thinks before starting to code, then there isn't so much extra
typing.

Typying is also reduced to a minimum with the help of some very nice XSLT
IDEs, e.g. the one I'm using -- XSelerator.


Happy holidays,

Dimitre Novatchev.



Keith Chadwick
12/28/2003 12:38:45 PM
I was not slagging off the language Dimitre and as a side note, in my
opinion I have a fairly good handle on it at this point, not anywhere near
your level but getting better each day. As for IDE's, I have been writing
code since the late 70's and no matter how good the IDE is it is not as good
as writing the code by hand. Also any good code implementation takes
thinking, that is unless you are a point and click developer.

And yes the language is lacking in some regards, yes it is verbose but it
is still a young language and like any language will go through improvements
in each generation. If it does not then it will end up being replaced by
other languages.

By the way during this whole thread, which was a discussion on Param's, you
never mentioned until now the proposed "tunnel parameters" and until you
have done 'every possible system implementation' with the language you can
not make a statement like 'although one can do without it in most cases.'.
For one as learned in the language as you, that seems like a very narrow
minded statement.

Happy Holidays
Keith


[quoted text, click to view]

Dimitre Novatchev
12/28/2003 8:51:29 PM
Keith,

[quoted text, click to view]

Then you don't read well...

[quoted text, click to view]

Nobody will ever have done this. Does this mean that people do not have the
right to share their experience? Let's then forbid any xslt-related forum...

[quoted text, click to view]

I am responsible for the statements I make.

During the three years I have participated in xslt-related news-groups there
was only one single request from a single xslt programmer for implementing
implicit parameters (tunnel parameters) and nobody else expressed the
necessity of such a feature.

I did not say that tunnel parameters are bad to have -- just that they are a
"nice to have" but not an essentially necessary feature.

[quoted text, click to view]


This statement is specific and based on facts and experience.


Cheers,

Dimitre.



Keith Chadwick
12/29/2003 11:02:51 AM
I think we are both stubborn. If we where in a pub talking politics over a
drink the owner would kick us out due to are incessant arguing :-)

Cheers
Keith

[quoted text, click to view]

Kathleen Dollard
12/31/2003 7:45:46 PM
Keith,

Just to clarify...

I did not say global parameters. I said global variables.

If I understand your scenario, you have data in your XML that you'd like to
use throughout templates, and the templates they call. That's an appropriate
scenario for global variables, and avoids excessive coupling between your
stylesheet and the calling code. Such coupling in some situations can be
hard to maintain.

--
Kathleen Dollard
Microsoft MVP
Author "Code Generation in Microsoft .NET"


[quoted text, click to view]
AddThis Social Bookmark Button