[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: XSLT 3.0 try/catch doubts

Subject: Re: XSLT 3.0 try/catch doubts
From: "Mukul Gandhi gandhi.mukul@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Mon, 25 Feb 2019 09:58:42 -0000
Re:  XSLT 3.0 try/catch doubts
Hi Mike,
    Thanks for a detailed explanation about my XSLT use case. I've now
tried new ways of using XSLT try/catch syntax, and below are my new
examples where try/catch appear to be more useful in the context of my
examples. I'm using Saxon 9.9.

Input XML:

<?xml version="1.0" encoding="UTF-8"?>
<test>
   <val>5</val>
   <val>4</val>
   <val>3</val>
   <val>0</val>
   <val>2</val>
   <val>0</val>
   <val>1</val>
</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"
                         xmlns:fn="http://xslt-functions"
                         xmlns:xs="http://www.w3.org/2001/XMLSchema"
                         exclude-result-prefixes="err fn xs"
                         version="3.0">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
       <result>
          <xsl:for-each select="test/val">
             <xsl:copy-of select="fn:div(5, ., position())"/>
          </xsl:for-each>
       </result>
    </xsl:template>

    <xsl:function name="fn:div" as="element()">
       <xsl:param name="numerator" as="xs:integer"/>
       <xsl:param name="denominator" as="xs:integer"/>
       <xsl:param name="pos" as="xs:integer"/>

       <xsl:try>
          <xsl:sequence>
     <div num="{$numerator}" denom="{$denominator}"><xsl:value-of
select="$numerator div $denominator"/></div>
          </xsl:sequence>
          <xsl:catch errors="*">
             <xsl:sequence>
       <error val_pos="{$pos}" document="{$err:module}" code="{$err:code}"
description="{$err:description}" location="line:{$err:line-number},
col:{$err:column-number}" />
     </xsl:sequence>
  </xsl:catch>
       </xsl:try>
    </xsl:function>

</xsl:stylesheet>

The above stylesheet, when applied to the input XML document, produces
following output,

<?xml version="1.0" encoding="UTF-8"?>
<result>
   <div num="5" denom="5">1</div>
   <div num="5" denom="4">1.25</div>
   <div num="5" denom="3">1.666666666666666667</div>
   <error val_pos="4"
          document="file:/E:/saxon/../foo.xsl"
          code="err:FOAR0001"
          description="Integer division by zero"
          location="line:26, col:0"/>
   <div num="5" denom="2">2.5</div>
   <error val_pos="6"
          document="file:/E:/saxon/../foo.xsl"
          code="err:FOAR0001"
          description="Integer division by zero"
          location="line:26, col:0"/>
   <div num="5" denom="1">5</div>
</result>

The above output is, what I wanted to achieve (i.e either emit the "div"
tag if div operation is successful, or emit an "error" tag if div by 0
error occurs). For each iteration of loop, my numerator is fixed (its also
non zero, and 5 in my example) and denominator is variable (it can be zero.
that div error I want to catch via try/catch, and continue processing
subsequent items in the loop).
I would have been more happy, if an error message could show line numbers
of the offending nodes from input XML document. For that, Saxon's extension
function line-number(..) seems to do the job well.

Below is another stylesheet (Stylesheet 2) processing things a little
differently, and working on the same input XML document,

<?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"
                         xmlns:fn="http://xslt-functions"
                         xmlns:xs="http://www.w3.org/2001/XMLSchema"
                         exclude-result-prefixes="err fn xs"
                         version="3.0">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
       <result>
          <xsl:try>
             <xsl:for-each select="test/val">
                <xsl:copy-of select="fn:div(5, .)"/>
             </xsl:for-each>
             <xsl:catch errors="*">
  <error document="{$err:module}" code="{$err:code}"
description="{$err:description}" location="line:{$err:line-number},
col:{$err:column-number}" />      </xsl:catch>
          </xsl:try>
       </result>
    </xsl:template>

    <xsl:function name="fn:div" as="element()">
       <xsl:param name="numerator" as="xs:integer"/>
       <xsl:param name="denominator" as="xs:integer"/>

       <xsl:sequence>
  <div num="{$numerator}" denom="{$denominator}"><xsl:value-of
select="$numerator div $denominator"/></div>
       </xsl:sequence>
    </xsl:function>

</xsl:stylesheet>

In the above stylesheet, I use the try/catch at a higher level (I enclose
the for-each loop within a try/catch). I get following output with this
XSLT transformation,

<?xml version="1.0" encoding="UTF-8"?>
<result>
   <error document="file:/E:/saxon/../foo1.xsl"
          code="err:FOAR0001"
          description="Integer division by zero"
          location="line:29, col:0"/>
</result>

This is expected. The transformation concludes after first failure, and
roll backs previous successful outcomes.

I'm happy with what I've learnt.

On Sat, Feb 23, 2019 at 11:37 PM Michael Kay mike@xxxxxxxxxxxx <
xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:

> 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.
>




--
Regards,
Mukul Gandhi

alt address : mukulgandhi@xxxxxxx

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.