|
[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] 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
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|

Cart








