Re: [xsl] [exsl] EXSLT 1.0 - Common, Sets and Math

Subject: Re: [xsl] [exsl] EXSLT 1.0 - Common, Sets and Math
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Mon, 5 Mar 2001 12:39:48 +0000
Hi Francis,

> Congratulations again. Stuff steam engines - when I grow up I want
> to write proposals as clear as Jeni's.

Thanks again :)

> re "Issue: exsl:reference-of" - the reference-of and add-result
> issues are so entwined. As you note, using the @select form of
> exsl:result does in fact give you return-by-reference. I now think
> that having an incremental return mechanism would probably cover the
> whole case - maybe exsl:result-set (is this any better than
> exsl:append?) with the same syntax and semantics as exsl:result,
> except the explicit assurance that it can be used iteratively to
> build up a result nodeset from its contents (by value) or from its
> select expression (by reference, assuming that the expression
> returns a nodeset).

I think that possibly the biggest problem with an incremental return
mechanism is controlling different return types. If we say that there
can be multiple exsl:result-set elements, each of which contributes to
the result, then we have to guard against situations like:

<exsl:function name="my:func">
   <exsl:result-set select="'string'" />
   <exsl:result-set select="0" />
   <exsl:result-set select="false()" />
      <node />
   <exsl:result-set select="$nodes" />

We don't want to get into a situation where we have different object
types in the same result.  We don't want to incrementally build
strings, numbers or booleans in this way.  RTFs can already be
incrementally built very easily, currently simply by building them at
the top level of exsl:function (previously by building them within a
variable that was then returned).  So if we have something like
exsl:result-set then it should only be used to reference nodes.

With exsl:result-set, we would say that the result of the function is
the result of unioning the node sets identified by the select
attributes of the exsl:result-set instructions that are instantiated.
Personally, I would prefer to encourage people to use
recursion to construct node sets within their functions, but I can see
how exsl:result-set would make some things much simpler. Perhaps a
good example is doc:key, which currently looks like:

<exsl:function name="doc:key">
   <xsl:param name="key-name" />
   <xsl:param name="key-value" />
   <xsl:param name="documents" select="/.." />
   <xsl:param name="base-URI" select="document('')" />
      <xsl:when test="exsl:object-type($documents) = 'string' or
                      count($documents) = 1">
         <xsl:for-each select="document($documents, $base-URI)">
            <exsl:result select="key($key-name, $key-value)" />
         <exsl:result select="doc:key($key-name, $key-value, 
                                      $documents[1], $base-URI) |
                              doc:key($key-name, $key-value,
                                      $documents[position() != 1],
                                      $base-URI)" />

with exsl:result-set, it would look like:

<exsl:function name="doc:key">
   <xsl:param name="key-name" />
   <xsl:param name="key-value" />
   <xsl:param name="documents" select="/.." />
   <xsl:param name="base-URI" select="document('')" />
   <xsl:for-each select="document($documents, $base-URI)">
      <exsl:result-set select="key($key-name, $key-value)" />

> Given that both sets of extension functions require the same
> infrastructure (xslt, exsl, and the com:eval function), and that you
> provide source for the functions in that infrastructure, I'd be
> inclined to put them in a single namespace, or at least a single
> proposal. OK, its inelegant, but as a transform author I'd rather
> not have to worry about whether adding a math function call to my
> set function calls will break the transform on someone's processor.

Hmm... the Set and Math functions don't require XSLT, EXSLT or
com:eval. They are supposed to be definitions of common extension
functions for XPath that could be implemented in any language and
could be used anywhere that XPath is used.  Their definitions are part
of EXSLT just as the definition of document() and key() are part of

The source that's provided in the appendix is only to give example
implementations using the method of defining functions that we're
developing in EXSLT. I could just as well give implementations in
Javascript etc. but would probably be jumped on for being
language-biased - I thought EXSLT might be fairly safe ;) But if
people want to generate implementations in their favourite language,
then I'll add those to the document as further illustrations and as a
source of code for implementors and authors.

So the idea is that there will be three types of XSLT processors:

 * processors that have built-in support for a function
 * processors that support EXSLT - Common
 * processors that don't support any of these extensions

If you provide an EXSLT implementation of one of these functions
within your stylesheet, then both the first two kinds of processors
will be able to process the function. You can test with
function-available(), but really that's always going to be an issue
whenever you use an extension function whether or not they use the
same namespace or are in the same proposal.

My reasoning was that dividing EXSLT into manageable chunks will
increase the likelihood that most processors will support EXSLT -
Common so that you can use that as a fallback if they don't support a
particular EXSLT extension function. Putting everything into one
proposal and saying that processors should support all of it places a
big burden on implementors and (I think) makes it more likely that
they'll just do things the way they want to do them.

Perhaps I'm being too cautious?



Jeni Tennison

 XSL-List info and archive:

Current Thread