- From: <bugzilla@jessica.w3.org>
- Date: Thu, 27 Mar 2014 13:12:21 +0000
- To: public-qt-comments@w3.org
https://www.w3.org/Bugs/Public/show_bug.cgi?id=25174 Bug ID: 25174 Summary: Buffering with xsl:try wrapped around xsl:stream or xls:result-document Product: XPath / XQuery / XSLT Version: Last Call drafts Hardware: PC OS: Windows NT Status: NEW Severity: normal Priority: P2 Component: XSLT 3.0 Assignee: mike@saxonica.com Reporter: abel.braaksma@xs4all.nl QA Contact: public-qt-comments@w3.org This bug report is a result of [1] and the response from the working group in [2]. The relevant quotes from the latter (minutes of 13 March 2014) are: Key example (edited to be valid): <xsl:try> <xsl:stream href="foo.xml"> <xsl:apply-templates mode="streaming"/> </xsl:stream> <xsl:catch /> </xsl:try> Key issue: xsl:try requires stable roll-back in case an error occurs that is caught by xsl:catch, even if that error is right at the beginning, i.e. when trying to read the source document. Quotes from the minutes: "ABr: but if you only want to catch a failure in opening the document, you've incurred the buffering cost for no benefit. And there's nowhere else to put the xsl:try in this case." "MK: yes, it would be nice to recover from a failure opening the input, without having to buffer all the output." "MK: this would suggest solution (3), an on-error output, but not sure how we would define the semantics. Basically, catching errors that occur before any output is written." Suggested solutions (mark #3) (1) disallow non-motionless expressions in xsl:try, which forces the programmer to do a copy prior to the xsl:try (2) define an extra attribute on xsl:output to make rollback behavior on xsl:try optional (3) make errors on xsl:stream uncatchable, or catchable only by a special attribute "on-error" (4) disallow xsl:stream inside xsl:try ------------------------------------------------------- The issue with xsl:try wrapped around xsl:stream effectively prevents (output) streaming, because the whole output is required to be buffered. This is not a problem if the result set is small, but if it is not, it will blow up streamability. The same issue occurs when xsl:try is wrapped around xsl:result-document, with one difference, the processor is not required to leave the result document in a stable state, i.e., it is possible to start writing output to a result document and _not_ rollback in case an error is raised. But this is not ideal either, as the user will be left with an uncertain state. Suggestion #3 The suggested resolution #3 above introduces a new attribute on xsl:stream, on-error, which could take an expression. The special variables defined under [3], like err:code and err:description are available inside this expression. Example: <xsl:stream href="foo.xml" on-error="my:report($err:code)"> <xsl:apply-templates mode="streaming"/> </xsl:stream> There is one additional drawback here, however. The special variables in the err: namespace are currently lexically scoped (see [3]), which means you will have to pass each error variable. A solution to this is to (also) allow the errors to be available as a map (as in $err:bag or $err:map), which gives advantages in this scenario and related scenarios, or to allow the special variables to be dynamically scoped, comparable to current-group. In the latter case you can write: <xsl:template match="/"> <xsl:stream href="foo.xml" on-error="my:report-errors()"> <xsl:apply-templates mode="streaming"/> </xsl:stream> </xsl:template> <xsl:function name="my:report-errors"> <xsl:message select="$err:description" /> </xsl:function> If we decide, however, to keep the current scope and variables for err:xxx, but we adopt static AVTs from [4], there is another way out for programmers to write this more effectively: <xsl:variable name="errorhandler" select="'my:report-errors($err:code, $err:description, $err:value)'" static="yes" /> <xsl:template match="/"> <xsl:stream href="foo.xml" on-error="{$errorhandler}"> <xsl:apply-templates mode="streaming"/> </xsl:stream> </xsl:template> <xsl:function name="my:report-errors"> <xsl:param name="errcode" /> .... <xsl:message select="$errcode" /> .... </xsl:function> IMO it is hard not to get enthusiastic about static AVTs, it seems to open up a whole new level of abstraction through preprocessing macros, that can greatly reduce many typical use-cases (but that's another subject, again, see [4]). Semantics for on-error: it will only catch errors that occur prior to starting reading the document, perhaps up until the root node, which is in line with current rules (somewhere we say that buffering of DTD and opening comments etc is required in streaming). Other errors ought to be caught the normal way, using more fine-grained xsl:try/xsl:catch. I propose to adopt this for xsl:stream and xsl:result-document, in the latter only to catch errors occurring from first attempt to writing the result document. Recovery actions: when on-error is defined and called, we might introduce a return value true/false that determines whether further processing should take place or not, or add one more attribute: on-error-terminate="yes|no". We may also decide on whether the result of on-error becomes part of the current result tree or not. See also: bug 25173. [1] https://lists.w3.org/Archives/Member/w3c-xsl-wg/2014Mar/0012.html [2] https://lists.w3.org/Archives/Member/w3c-xsl-wg/2014Mar/0014.html [3] https://www.w3.org/TR/xslt-30/html/Overview.html#element-try [4] https://www.w3.org/Bugs/Public/show_bug.cgi?id=24619 -- You are receiving this mail because: You are the QA Contact for the bug.
Received on Thursday, 27 March 2014 13:12:24 UTC