RE: [xsl] Saxon bug in short-circuiting of expressions?

Subject: RE: [xsl] Saxon bug in short-circuiting of expressions?
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Mon, 24 Jul 2006 11:30:02 +0100
Which version of Saxon are you using? The XSLT 2.0 spec differs from XSLT
1.0 in this area.

Either way, the "forwards-compatible processing" section of the XSLT 1.0
spec makes no difference. Your stylesheet is using version="1.0" so
forwards-compatible processing is not enabled. 

The relevant provision is in fact XSLT 1.0 section 14.2, which says:

If the XSLT processor does not have an implementation of an extension
function of a particular name available, then the function-available
function must return false for that name. If such an extension function
occurs in an expression and the extension function is actually called, the
XSLT processor must signal an error. An XSLT processor must not signal an
error merely because an expression contains an extension function for which
no implementation is available.

A decision was made to change this rule for XSLT 2.0, which introduces
compile-time conditionals in the form of the use-when attribute. You can now
write:

<xsl:template match="/">
    <xsl:if use-when="function-available('hoge')"
test="hoge()">moge</xsl:if>
</xsl:template>

If you want to write code that works under both 1.0, and 2.0, use
version="2.0" in your xsl:stylesheet element, and write:

<xsl:template match="/">
    <xsl:if use-when="function-available('hoge')" 
            test="function-available('hoge') and hoge()">moge</xsl:if>
</xsl:template>

The reason for the change is that XSLT has generally moved to be a stricter
programming language with stronger error detection and reporting, and less
of an interpretive scripting language.

There's also another independent change in XPath 2.0, which is that the
order of evaluation of the operands of "and" and "or" is no longer
well-defined, except in backwards compatibility mode. This is to allow
database products to exploit indexing, for example if you write
//customer[age>60 and id='123456'] then an index on "id" can be used.

Michael Kay
http://www.saxonica.com/ 



> -----Original Message-----
> From: Michael(tm) Smith [mailto:smith@xxxxxxxxxxxxxxxxxx] 
> Sent: 24 July 2006 11:08
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Saxon bug in short-circuiting of expressions?
> 
> I have a question about a difference in the way that Saxon 
> handles evaluation of calls to unknown functions in boolean 
> expressions.
> 
> Applying the following stylesheet to itself or on any other 
> instance, I'd expect it would produce no errors and no output.
> 
>   <xsl:stylesheet version="1.0" 
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
>     <xsl:output method="text"/>
>     <xsl:template match="/">
>       <xsl:if test="function-available('hoge') and 
> hoge()">moge</xsl:if>
>     </xsl:template>
>   </xsl:stylesheet>
> 
> If I try it with xsltproc, that is exactly what I get (no 
> errors, no output). But trying it with Saxon, I get a fatal error:
> 
>   Error in expression function-available('hoge') and hoge(): 
> Unknown system function: hoge
> 
> I know that the "Forwards-Compatible Processing" section of 
> the XSLT 1.0 spec mentions that if an
> 
>   expression calls a function with an unprefixed name that is not
>   part of the XSLT library, then an error must not be signaled
>   unless the function is actually called.
> 
> But I'd think that Saxon would just short-circuit the 
> expression, never getting to actually evaluating the right 
> operand -- the call to the hoge() function -- since the XPath 
> spec says:
> 
>   An and expression is evaluated by evaluating each operand and
>   converting its value to a boolean as if by a call to the boolean
>   function. The result is true if both values are true and false
>   otherwise. The right operand is not evaluated if the left
>   operand evaluates to false.
> 
> In this case, function-available('hoge') evaluates to false, 
> so it seems like the call to hoge() should not be getting evaluated.
> 
> Or am I misreading the spec?
> 
>   --Mike

Current Thread