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

Re: Designs for XSLT functions (Was: Re: [xsl] RE: syntax sugar for call-template)


Subject: Re: Designs for XSLT functions (Was: Re: [xsl] RE: syntax sugar for call-template)
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Mon, 19 Feb 2001 20:15:40 +0000

Hi David,

> Yes, my proposal relies on a conditional construct in XPath. I think
> it's more worthwile to try and get such a thing in as early as
> possible than to try and figure out a intuitive and concise
> definition of how the mix of XPath and arbitrary template
> instructions should behave.

So you would advocate having the development of exsl:function include
adding exsl:if()?

I think that the only real objection I would have to this is that
conditional constructs in XPath can only go so far and get incredibly
messy if they're more that a little complex.  For example:

   <xsl:choose>
      <xsl:when test="foo">
         <xsl:choose>
            <xsl:when test="bar"><xsl:return select="0" /></xsl:when>
            <xsl:otherwise><xsl:return select="1" /></xsl:otherwise>
         </xsl:choose>
      </xsl:when>
      <xsl:when test="baz"><xsl:return select="2" /></xsl:when>
      <xsl:otherwise><xsl:return select="3" /></xsl:otherwise>
   </xsl:choose>

is:

  <xsl:return select="exsl:if(foo,
                              exsl:if(bar, 0, 1),
                              exsl:if(baz, 2, 3))" />

Admittedly it's not particularly pretty in XSLT, but if you replace
numbers with complex string manipulation and add a few more xsl:whens
in different places and so on then I think the XPath-only version
becomes pretty unworkable. My personal opinion - I'm very willing to
be shouted down.

[Aside: Of course as soon as we have exsl:function we can do:

<exsl:function name="my:if">
   <xsl:param name="cond" />
   <xsl:param name="true" />
   <xsl:param name="false" />
   <xsl:choose>
      <xsl:when test="$cond"><exsl:return select="$true" /></xsl:when>
      <xsl:otherwise><exsl:return select="$false" /></xsl:otherwise>
   </xsl:choose>
</exsl:function>

How great is that going to be!]
   
> I think your example with xsl:for-each shows that this isn't
> straight forward. You would have to recursively allow and dissalow
> constructs for descendants of a xsl:function.

That's true. It would be good to hear from implementers whether it's
hard to implement a check of this kind of conditional content. On the
other hand, we shouldn't be restricted to only allowing content models
that are easy to represent in DTDs - half of XSLT would disappear if
we were! :) A line that says:

  "It is an error if the result of instantiating the content of
  exsl:function involves the creation of any nodes. A processor may
  signal this error; if it does not signal the error, it must recover
  by ignoring the nodes."

would, I think, cover the 'no result tree nodes' commandment.

Oh, and I've thought of a couple of reasons to have xsl:for-each.
Firstly, as we know, key() and id() are restricted to finding nodes in
the current tree. If I want to use an extension function that
retrieves keyed nodes in a particular document then I need to be able
to do:

<exsl:function name="my:key">
   <xsl:param name="key-name" />
   <xsl:param name="key-value" />
   <xsl:param name="file-name" />
   <xsl:param name="base-node" select="/" />
   <xsl:for-each select="document($file-name, $base-node)">
      <exsl:result select="key($key-name, $key-value)" />
   </xsl:for-each>
</exsl:function>

Another example is if I want to use the built-in sort algorithms to
find, for example, the first value alphabetically in a node set:

<exsl:function name="my:first-alphabetical">
   <xsl:param name="nodes" />
   <xsl:for-each select="$nodes">
      <xsl:sort />
      <xsl:if test="position() = 1">
         <exsl:result select="." />
      </xsl:if>
   </xsl:for-each>
</exsl:function>

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/



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



Current Thread
Keywords