Hi Duane,
see my comments below...
Duane Gran wrote:
XSL experts,
I have an XSL which loops over a set of elements in search of links
and creates a result document for the link. In some cases there is
more than one link to the same anticipated document, so I use the
doc-available() to test first for its existence before creating the
file.
which is good.
This is intended to avoid a DynamicError related to writing more than
one result document to the same URI.
which is bad, you won't be able to: regardless your structure, or the
use of the doc-available() function, having an instruction
xsl:result-document that writes more than once to the same target is
illegal and raises an (I believe recoverable) error.
<snip />
BUILD FAILED
/Users/dgran/dev/rose/build.xml:395: The following error occurred
while executing this line:
/Users/dgran/dev/rose/build.xml:77: net.sf.saxon.trans.DynamicError:
Cannot write more than one result document to the same URI:
file:/Users/dgran/dev/rose/build/zoom/1-1861.wrenn.320-321.img.html
Indeed.
In the first case, the file (1-1861.wrenn.320-321.img.html) is
correctly created because it doesn't exist yet. In the second case
the doc-available() method should return true
sorry, no: it will always return false() during one run, and writing
twice to the same target will always return and error, though as a
result of optimization, the second may not always occur.
This is because in XSLT you can't predict, in any way, the order of
execution. Hence, it is impossible to say "first" case and "second" case
(well, you can say it, but the processor may or may not run in that order).
and skip the result-document command, but it fails to work. My
hypothesis is that the result-document() method isn't finished
flushing before the call to doc-available() is made.
No, doc-available() always returns the same result, and regardless of
its result, xsl:result-document may not write more than once to the same
URI.
Assuming my guess is correct, is there a way in XSL to assure that the
document is finished writing before continuing to the next iteration
in the loop?
No, this is imperative thinking. Try to think declarative ;)
It is impossible to control flushing, because it is impossible to
predict the execution order.
Maybe there is another way of skinning this cat.
Yes, see below.
I welcome suggestions. I'm using Saxon 8-7-3j. Below is a simplified
version of my stylesheet:
Please update, you use a version that was written based on an earlier
draft of the standard. Version 8.9 is now current.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:template match="/">
<xsl:for-each select="ram|//repro|//page|//figure">
why use for-each? Consider xsl:apply-templates.
<xsl:variable name="zoomhtml">
<xsl:text>build/zoom/</xsl:text>
<xsl:value-of select="@image"/>
<xsl:text>.img.html</xsl:text>
</xsl:variable>
<xsl:message>
test for doc <xsl:value-of select="$zoomhtml"/> available:
<xsl:value-of select="doc-available($zoomhtml)"/>
Remember, since the order of the execution is undetermined, so is the
order of the output of the xsl:message instruction.
</xsl:message>
<xsl:choose>
<xsl:when test="doc-available($zoomhtml)"/>
You really don't need this... (see below)
<snip />
Here's a solution that I normally use. Take all URIs that you want to
write to, pack them in a sequence and deduplicate them (use the function
distinct-values or similar) and go from there (if possible) or, if you
can't, you can use a micro-pipeline. I.e., the first transforms and
changes the input and adds _1, _2 etc to the names, to ensure
uniqueness, the second is the transformation where you create the actual
result document.
Both approaches will work always. The first dismisses writing documents
to URIs that are duplicates, but uses the original URI, the second
always writes something, but changes the target URI a bit, which may or
may not be convenient. Whichever you choose is up to your requirements.
HTH,
Cheers,
-- Abel Braaksma
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--