Re: [xsl] XSLT 3.0 try/catch doubts

Subject: Re: [xsl] XSLT 3.0 try/catch doubts
From: "Michael Kay mike@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Sat, 23 Feb 2019 18:07:30 -0000
Division by zero is a dynamic error, but if the operands are constants, then
most processors will be able to detect it statically, because evaluating
constant subexpressions is a very simple optimization.

So what do the rules say about dynamic errors? The detailed rules are in
B'2.14 https://www.w3.org/TR/xslt-30/#errors -- which doesn't actually mention
try/catch.

The key paragraph is

<quote>
An implementation may signal a dynamic error before any source document is
available, but only if it can determine that the error would be signaled for
every possible source document and every possible set of parameter values. For
example, some circularity errors fall into this category: see 9.11 Circular
Definitions.
</quote>

This isn't quite as rigorous as it might be. In your second example, there are
clearly source documents for which the error will never be raised dynamically
(those where count(/test/hello) is zero) and therefore it must not be raised
statically. In the first example, the error will always be raised so long as
the match="/" template is executed, that is, if evaluation starts in the
unnamed mode; that leaves some scope for interpretation of exactly what the
above paragraph is supposed to mean (should it be read as saying "and for
every possible initial mode"?). Also the cited paragraph isn't really clear as
to what "would be signaled" means: if an error happens, but is not reported
because it is caught by try/catch, then is it "signaled" for the purpose of
this rule? The whole thing is a bit fuzzy round the edges.

What's happening in Saxon, though, is quite wrong. Saxon goes to great lengths
to avoid raising the error statically; however the optimizer somehow rewrites
the logic so that the constant expression (1 div 0) is evaluated outside the
try/catch and the error therefore occurs at run-time, but isn't caught. I'll
pursue that as a bug, even though the spec is a little fuzzy.

Michael Kay
Saxonica



> On 22 Feb 2019, at 09:58, Mukul Gandhi gandhi.mukul@xxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>
> Hi all,
>     I've been trying to do one of XSLT 3.0 transformation using XSLT 3.0's
try/catch syntax. Below are my examples, and my questions thereafter. I'm
using Saxon EE 9.9 as an XSLT processor.
>
> Input XML:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <test>
>     <hello/>
>     <hello/>
>     <hello/>
>     <hello/>
>     <hello/>
> </test>
>
> Stylesheet 1:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>                          xmlns:err="http://www.w3.org/2005/xqt-errors";
>                          exclude-result-prefixes="err"
>                          version="3.0">
>
>     <xsl:output method="xml" indent="yes"/>
>
>     <xsl:template match="/">
>         <xsl:try>
>             <xsl:value-of select="for $x in (1 to count(test/hello)) return
(1 div 0)"/>
> 	    <xsl:catch errors="*">
> 	         <error code="{$err:code}" description="{$err:description}"
location="line:{$err:line-number}, col:{$err:column-number}"/>
> 	     </xsl:catch>
>         </xsl:try>
>     </xsl:template>
>
> </xsl:stylesheet>
>
> This transformation (Stylesheet 1) with the specified input XML, gives me
following output,
>
> Error evaluating (1 div 0) in xsl:value-of/@select on line 11 column 87 of
foo1.xsl:
>   FOAR0001: Integer division by zero
> Integer division by zero
>
> Stylesheet 2:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>                          xmlns:err="http://www.w3.org/2005/xqt-errors";
>                          exclude-result-prefixes="err"
>                          version="3.0">
>
>     <xsl:output method="xml" indent="yes"/>
>
>     <xsl:template match="/">
>         <xsl:try>
>              <xsl:value-of select="for $x in (1 to count(test/hello)) return
($x div 0)"/>
> 	     <xsl:catch errors="*">
> 	         <error code="{$err:code}" description="{$err:description}"
location="line:{$err:line-number}, col:{$err:column-number}"/>
> 	     </xsl:catch>
>         </xsl:try>
>     </xsl:template>
>
> </xsl:stylesheet>
>
> (the difference of this stylesheet, from the previous one is having $x div 0
instead of 1 div 0 so as to try best not to halt during static analysis of
stylesheet. This I think, forces the XSLT processor to process the input XML
document and do the transformation)
>
> This transformation (Stylesheet 2) with the same specified input XML, gives
me following output,
>
> <?xml version="1.0" encoding="UTF-8"?>
> <error code="err:FOAR0001"
>           description="Integer division by zero"
>           location="line:11, col:43"/>
>
> My questions are,
> In the first case (Stylesheet 1), is XSLT processor able to determine from
static analysis of stylesheet that 1 div 0 (which is written in a "for"
expression) is a problem, and the XSLT processor doesn't progress with actual
transformation (i.e reading input XML and transforming it)?
>
> I think, with Stylesheet 2 since the div by 0 expression is written as $x
div 0, the div by 0 error can only be found as a dynamic error.
>
> Needless to mention, I've found XSLT 3.0's try/catch instruction to be quite
useful.
>
> Any thoughts and comments, related to the mentioned points would be great.
>
>
>
>
> --
> Regards,
> Mukul Gandhi
>
> alt address : mukulgandhi@xxxxxxx
> XSL-List info and archive
> EasyUnsubscribe (by email)

Current Thread