xsl-list
[Top] [All Lists]

Re: [xsl] Keeping result-document() from writing to a file more than once?

2019-04-19 10:02:16
If you are trying to create a single result copy of elements that are multiply 
referenced then I would suggest using XSLT 3 so you can use maps. (OT 2.5.4 and 
3.3+ both use Saxon 9.8 so you can mix XSLT 2 and 3 modules if you're running 
your transform in the OT.)

Then you can process your input files to construct a map of uri/id pairs (the 
key) to the elements and then process that map to generate the results (and if 
this is to create referenceable content topics for Ixiasoft, remind them that 
this aspect of their architecture is very poorly thought out and they should 
not require it, but that's another conversation).

If you construct map entries for each use and then combine them into a single 
map using the "use-first" or "use-any" "duplicates" option then you can blindly 
process all the references and let the map-merge process produce a single list 
of elements, e.g.;

<xsl:variable name="use-entries" as="map(*)*">
  <xsl:call-template name="find-all-conrefs"/>
</xsl:variable>

The find-all-conrefs template generates maps, one for each id/element pair, 
which you can create with xsl:map or using the literal map constructor: 
"map{$key : $value}".

Now make a single map:

<xsl:variable name="use-map" as="map(*)"
  select="map:merge($use-entries, map{ 'duplicates' : 'use-any'}"
/>

And then process the entries to produce the result docs:

<xsl:for-each select="map:keys($use-map)">
  <xsl:variable name="key" select="." as="xs:string"/>
  <xsl:call-template name="make-result-doc">
    <xsl:with-param name="key" as="xs:string" select="$key"/>
    <xsl:with-param name="key" as="element() " select="map:get($use-map, $key)" 
as="element() "/>
  </xsl:call-template>
</xsl:for-each>

(I know the for-each could be done in slightly more compact way but I like to 
be a little more explicit when working with maps.)

I find using maps for this kind of gathering and outputting process makes the 
code clearer, especially for tasks that are more "procedural" than typical XSLT 
document processing.

Cheers,

E.
--
Eliot Kimber
http://contrext.com
 

On 4/18/19, 4:56 PM, "dvint(_at_)dvint(_dot_)com" 
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> wrote:

    I'm processing some DITA xml files with XSLT. I'm reading these files and 
where they have a conref into some other content (think xinclude) that is 
included in the current file. There may be multiple things shared out from one 
large file (topic). I want to make a new file for each of the shared pieces.
     
     More than one file can reference exactly the same content, so after 
processing all these files I want a single file representing the shared 
content. It is this multiple references to the same content that causes the 
duplication of the file that the result-document() function doesn't like. this 
is the code that I have for detecting this situation:
     
     <xsl:variable name="newFile" select="concat($srcFile, '-', $target, 
'-output.dita')" />
     
     
     
     NEW FILE <xsl:value-of select="$newFile"/> 
     
     Doc available: <xsl:value-of select="doc-available($newFile)"/> 
     
     
     <xsl:if test="not(doc-available($newFile))" 
     
     CREATE FILE NOW 
     
     <xsl:result-document method="xml" href="{$newFile}" indent="yes">
     <referable-content id="ikj1555615661716" xml:lang="en-us">
     <titler>efereable test</title>
     <rcbody>
     <xsl:copy-of select="document($srcFile)//*[@id = $target]"/>
     </rcbody>
     </referable-content>
     </xsl:result-document>
     
     </xsl:if>
     
     
     
     
     
     Here are a series of messages created as i process the files. Notice that 
the first message correctly identifies the file 
"conref-para_content.dita-simpletable_nohead-output.dita" as not existing and 
produces output. If you then look at the last one you will see the same file 
being referenced and tries to write to the file again. But in other places you 
see the test working properly and not creating a new file:
     
     
     
     
     
     file 'conref-para_content.dita' 
     NEW FILE 
/Users/danvint/pubsrc-other/formatting-sample/conref-para_content.dita-simpletable_nohead-output.dita
     Doc available: false'
     
     CREATE FILE NOW
     
     file 'conref-para_content.dita' 
     NEW FILE 
/Users/danvint/pubsrc-other/formatting-sample/conref-para_content.dita-simpletable_head-output.dita
     Doc available: true'
     
     file 'conref-para_content.dita' 
     NEW FILE 
/Users/danvint/pubsrc-other/formatting-sample/conref-para_content.dita-table_head-output.dita
     Doc available: true'
     
     file 'conref-para_content.dita' 
     NEW FILE 
/Users/danvint/pubsrc-other/formatting-sample/conref-para_content.dita-table_nohead-output.dita
     Doc available: true'
     
     file 'conref-para_content.dita' 
     NEW FILE 
/Users/danvint/pubsrc-other/formatting-sample/conref-para_content.dita-simpletable_nohead-output.dita
     Doc available: false'
     
     CREATE FILE NOW
     
     
     
    I believe the doc-available() reads the file to be XML. So when the script 
stops there is a file in the OS but it is empty due to the second write 
failing. Running this in oXygen I get the results of what should have been 
written showing up in a window. I cut and pasted that content into the empty 
file and reran it. Processing got further along and stopped on a second file 
with the same message. I did the same thing, with the new content in this 
second file and it now runs to completion if all the files exist.
    
    If I delete all the files that were generated, I'm back to the same 
problem. Is there some delay in writing the output that I should  be accounting 
for? Is there a sleep() function in XSLT or something to cause a delay or flush 
the buffer?
     
     Any ideas on what I can check?
     
     
     
     ..dan
    XSL-List info and archive 
<http://www.mulberrytech.com/xsl/xsl-list>EasyUnsubscribe 
<http://lists.mulberrytech.com/unsub/xsl-list/1278982>
    (by email <>)
    
    
    
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--

<Prev in Thread] Current Thread [Next in Thread>