xsl-list
[Top] [All Lists]

Re: [xsl] XSLT 3.0 try/catch doubts

2019-02-23 12:07:37
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 §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(_dot_)mukul(_at_)gmail(_dot_)com 
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> 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(_at_)acm(_dot_)org
XSL-List info and archive
EasyUnsubscribe (by email)
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--

<Prev in Thread] Current Thread [Next in Thread>