- From: Andre Cusson <ac@hyperbase.com>
- Date: Sun, 26 Jan 2003 15:47:06 -0500
- To: public-qt-comments@w3.org
- Cc: michael.h.kay@ntlworld.com, saxon-help@lists.sourceforge.net
Hi, I would like to make a case for the removal of the restriction imposed on the result-document instruction when writing to a temporary result tree. The proposal states: [ERR146] It is a dynamic error to evaluate the xsl:result-document instruction when the current destination node is not a node belonging to a result tree (for example, when it is a node belonging to a temporary tree). The processor must signal the error. . This means, for example, that it is an error to use xsl:result-document when the tree containing the current destination node is a temporary tree created using xsl:variable, or a tree created using xsl:message, xsl:attribute, etc and, as I understand, the issue that brought this restriction was related to limiting side-effects and a typical case was stated as: But let's take a global variable <xsl:variable name="x"> <xsl:result-document ...> <a/> </ </ The variable is never referenced. Should the result document be output, or not? There are a few alternatives to answer this question, but restricting result-document is not the right one because it is much to restrictive. In fact it blocks recursion for serialization of documents which I would think is one of the last things to do in a functional environment. XSLT is functional programming and functional programming is recursion for recursive structures. Blocking recursion is defeating the main purpose. Here is a brief summary of the issue. First a trivial example where a "Cannot switch to a final result destination while writing a temporary tree" error on the line marked with an x is generated when the processor (ex: Saxon v7.3.1 reaches the recursive call to 'publish' and executes the 'make-page' template from there. <xsl:output name="outputf-format" .../> <xsl:template name="make-page"> <xsl:param name="src-nodeset"/> <xsl:param name="fname"/> x <xsl:result-document format="output-format" href="{$fname}"> ... <xsl:copy-of select="$src-nodeset"/> ... </xsl:result-document> </xsl:template> <xsl:template name="publish"> <xsl:param name="src-nodeset"/> <xsl:for-each select="$src-nodeset/section"> ... <xsl:call-template name="make-page"> <xsl:with-param name="fname" select="@id"/> <xsl:with-param name="src-nodeset"> ... <xsl:for-each select="sub-section-group"> <xsl:call-template name="publish"> <xsl:with-param name="src-nodeset" select="."/> </xsl:call-template> </xsl:for-each> </xsl:with-param> </xsl:call-template> <xsl:for-each> </xsl:template> Writing a secondary document is not a side effect, it is simply dealing with (serializing to) the real world where information is mapped to finite flat files like web pages. It seems to us like a major impediment if a style sheet is limited to outputting a single page at a time, without recursion. We have here an application with 10 to 20K lines of XSLT, processing millions of lines of streaming and static XML into infinitely complex documents for printed and interactive access. There are many issues involved and performance is one of them. One of the keys is to stream and process graphs and structures efficiently. Recursion and not having to reprocess the same (often very large) structures iteratively is crucial. So as one traverses such structures, gathering data and building a page, and one finds information there that warrants a sub page (and so on recursively), one needs to also produce those pages. With the current restriction, the only alternative is to iteratively process and reprocess the structure(s), building multiple temporary trees and variables, recalculating values and node sets until the full depth of the structure(s)I has been reached and all sub-pages at all levels of the recurring structure have been generated. This is using iteration to deal with recursion. It is not only (very) inefficient and awkward (and not streamable), it is plain ugly. The example code here was purposely simple to show where the error message occurred but we do have real world examples and they are far more intricate. This feature is required by a few major modules in our application (ex: publishing, O-R mapping, invoicing, etc.). We built this application with Saxon v6.5.2 that complied to the XSLT 1.1 draft which defined a "document" instruction that did not have this restriction on changing the final output document while writing to a temporary tree. Our application works fine with Saxon v6.5.2 (XSLT v1.1) but cannot be ported to Saxon 7.3.1 (XSLT v2.0) for this single reason. This is a major limitation to us. But we also feel that it is a major limitation for XSLT. Of course side-effects should be avoided but preventing recursion (for serialisation) is not the right way, because the cost is to high and out weights the benefits. As for the unused global variable with a result-document in the initial example above, I tend to believe that if the variable is unused, the document should probably not be output and the processor should probably signal that the variable is not used (and (possibly) that the document will not be output). Other solutions could also be acceptable to us, including outputting the document anyway or even, as was suggested, that the document be output only if the temporary tree gets copied to the final result tree. We would be happy to contribute in any way on the resolution of this issue (changing final output while writing a temporary tree) so do not hesitate to contact us. Thank you. Regards, Andre Cusson ac@hyperbase.com Tel: (1) 514 984 1601 01 Communications Inc. 11840 Norwood Avenue Montreal, QC, H3L 3H7
Received on Sunday, 26 January 2003 15:38:42 UTC