xsl-list
[Top] [All Lists]

RE: [xsl] loop timing and result-document flush

2007-05-02 10:13:10

Could I attempt a summary?

Firstly, as David C pointed out, for-each is not a loop. Think of it as
processing all the items in parallel, even if the implementation chooses to
do it sequentially.

Secondly, you're not allowed to read a document that was written earlier in
the transformation. That applies to doc-available() just as much as to
doc().

Thirdly, and this has also been said already, though perhaps not very
clearly: your problem description essentially says that you are eliminating
duplicates, and the right tools for that job in XSLT 2.0 are
distinct-values() and xsl:for-each-group.

Fourthly, your strategy doesn't work because doc-available() is defined to
be stable. Once you've called doc-available('abc.xml') and have received the
answer "false", the system is obliged to continue returning the answer false
if you call the function again with the same argument. [That's the way it is
supposed to work. To be honest, I'm pleasantly surprised Saxon is getting
this right, and I wouldn't guarantee that it will do so in all
circumstances!]

Michael Kay
http://www.saxonica.com/ 

-----Original Message-----
From: Duane Gran [mailto:dmg2n(_at_)virginia(_dot_)edu] 
Sent: 02 May 2007 15:06
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] loop timing and result-document flush

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.  This is intended to avoid a DynamicError related 
to writing more than one result document to the same URI.

However, when I run the program against a large set of 
documents after 10 minutes or so I get the DynamicError.  
Below is the output (run via ant) along with some debugging 
fields I'll explain in a moment:

      [xslt]         test for doc /Users/dgran/dev/rose/build/zoom/ 
1-1861.wrenn.320-321.img.html  available: false
      [xslt]           creating file: /Users/dgran/dev/rose/build/ 
zoom/1-1861.wrenn.320-321.img.html

      [xslt]         test for doc /Users/dgran/dev/rose/build/zoom/ 
1-1861.wrenn.320-321.img.html  available: false
      [xslt]           creating file: /Users/dgran/dev/rose/build/ 
zoom/1-1861.wrenn.320-321.img.html

      [xslt] Failed to process /Users/dgran/dev/rose/deploy.temporary/
1-1861.wrenn.rad.xml

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

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

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?  Maybe there is another way 
of skinning this cat.  I welcome suggestions.  I'm using 
Saxon 8-7-3j.  Below is a simplified version of my stylesheet:

<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">
       <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)"/>
       </xsl:message>
       <xsl:choose>
         <xsl:when test="doc-available($zoomhtml)"/>
         <xsl:otherwise>
           <xsl:message> creating file: <xsl:value-of 
select="$zoomhtml"/>
           </xsl:message>
           <xsl:result-document href="$zoomhtml"> 
</xsl:result-document>
         </xsl:otherwise>
       </xsl:choose>
     </xsl:for-each>
   </xsl:template>
</xsl:stylesheet>

Duane Gran

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



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