Re: XT extension mechanism

Subject: Re: XT extension mechanism
From: James Clark <jjc@xxxxxxxxxx>
Date: Wed, 06 Jan 1999 12:09:08 +0700
Flow Simulation wrote:

> I just meant that, for a very simple case,
> it strikes me as simpler to evaluate in-line within the template.     Example:
> 
> <xsl:template match="amount">
>   <H2>Chapter <xsl:eval>formatNumber(childNumber(this) + 5)</xsl:eval></H2>
>   <xsl:apply-templates/>
>   <H2>....here ends Chapter <xsl:eval>formatNumber(childNumber(this) + 5)</xsl:eval></H2>
> </xsl:template>
> 
> To do the same with <filter> you have to do some programming to get a handle
> to the result text and manipulate it.    That might seem simple enough to SAX users,
> or programmers in general, but one would hope that XSL would be usable by people who are
> only familiar with writing HTML and a bit of JavaScript.

I would hope XSL was usable without any need for script.

But I take your point. I think a lot of extensibility problems can be
reduced to a string-to-string manipulation problem, for example,
stripping whitespace, converting between units.  Even something like
totalling a list of numbers can be handled as a string to string
transformation on a part of the result (you use normal XSL facilities to
construct a space-separated list of numbers; then use the extension
mechanism to map from the string containing the space-separated list of
numbers to the string containing the total).  This is particularily the
case at the moment, since XSL doesn't have any built-in string
manipulation facilities.  For this kind of extensibility problem, there
could be a special case of xsl:filter that makes things simpler.  For
example your particular example could be handled using something like

  <xsl:transform-string script="Number(this)+5">
    <xsl:number/>
  </xsl:transform-string>

xsl:transform-string would be a special case of xsl:filter.  It creates
a string from the text content of the result tree fragment being
filtered, applies the script to that string, and replaces the result
tree fragment by a single text node containing the result of evaluating
the script.

Your example illustrates a problem I think xsl:eval suffers from.  You
needed a non-standard childNumber() function, even though XSL already
provides this functionality via the xsl:number element.  An extension
mechanism that works just on the source tree ends up requiring the
existing XSL facilities to be duplicated in the script language.

> But is a mechanism which acts purely on the _result_ tree adequate?

It's definitely adequate in theory.  You can always copy any parts of
the source tree that you need over to the result tree fragment that
you're filtering.  On the other hand this might be inconvenient in
practice. I think some practical experience is needed to see whether the
result tree alone is sufficient.

> Are you thinking of supporting an <xsl:filter> _and_ an <xsl:eval>?
> Can you use the DOM to read the source tree as well as the result tree fragment?

If the result tree alone isn't sufficient, I think it would be better to
extend xsl:filter to give it access to the source tree as well rather
than adding another separate extension facility with a different model. 
For example, in the object-like case you could allow the arguments of
xsl:filter to be lists of nodes in the source tree instead of just
strings.

Allowing access to the source tree via the DOM has some problems.  What
happens if you use the DOM to mutate the source tree? That's really
scary. Also there's some loss of implementation flexibility.  If the
filtering mechanism just has access to the result it can be done as a
completely separate process from the rest of the transformation.  You
could do the XSL processing minus the filtering on the server, and do
the filtering on the client.
 
> But what if you need some value computed from elements of another subtree, say.
> Would you be forced to put the <xsl:filter> around templates which
> matched near the root of the source tree, and use the DOM within
> the filter object to "fix up" the result tree starting near the root?   I think this
> would result in the same problems as having global state.

Yes, exactly the same problems.  An xsl:filter around the root of the
result tree is just as problematic as script. The advantage of
xsl:filter is that you don't have to put xsl:filters round the root. 
Often they can be just around a single node.  In the more complex cases,
you might need to put an xsl:filter around an element such as a table. 
Very rarely will they need to be around the root.  xsl:filter can't stop
you writing extensions that will work very slowly; nothing that allows
access to a full scripting language can.  But it makes it easy to write
extensions that can run fast even in a WYSIWYG environment.

James


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


Current Thread