Search code examples
xsltxquerysaxon

fn:transform running with default call-template invocation - no result-documents created


This transform test.xsl copies (for the purpose of a small test example) a directory of XML data by calling an identity transform for each recursively encountered XML file.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns:fn="http://www.w3.org/2005/xpath-functions"
                xmlns:map="http://www.w3.org/2005/xpath-functions/map"
version="3.0" exclude-result-prefixes="xsi fn xs map" expand-text="yes">
   <xsl:output method="xml" indent="yes"/>
   <xsl:strip-space elements="*"/>
   
   <xsl:variable name="currentStylesheet" as="document-node()" select="doc('identity.xsl')"/>
   <xsl:template name="xsl:initial-template">
      <xsl:for-each select="collection('file:///mnt/c/home/oneD/data/translatable' || '?select=*.xml;recurse=yes')">
         <xsl:result-document href="{replace(document-uri(),'/data/translatable/','/translated/')}">
              <xsl:sequence select=" fn:transform(map {
                                   'stylesheet-node' :  $currentStylesheet,
                                   'source-node'     :  .
                       })?output"/>
         </xsl:result-document>    
      </xsl:for-each>
   </xsl:template>
 </xsl:stylesheet>

However if I invoke it from XQuery with fn:transform like so

xquery version "3.1";
fn:transform(map { 'stylesheet-node' :  doc('test.xsl')})?output 

none of the result-documents are created.

Is there something wrong with the invoking XQuery? I have never before tried this so it is my best attempt from reading the docs. Running on Saxon 10.3


Solution

  • The fn:transform function doesn't write anything to the file system, it returns a map with

    one entry in the map for the principal result document, and one for each secondary result document. The key is a URI in the form of an xs:string value. The key for the principal result document is the base output URI if specified, or the string "output" otherwise. The key for secondary result documents is the URI of the document, as an absolute URI. The associated value in each entry depends on the requested delivery format. If the delivery format is document, the value is a document node. If the delivery format is serialized, the value is a string containing the serialized result

    If you want to write result documents to the file system you need to do that in your code processing the map returned by the transform function, for instance with fn:put or the EXPath file module.

    The option map for the transform function also has a hook post-process:

    A function that is used to post-process each result document of the transformation (both the principal result and secondary results), in whatever form it would otherwise be delivered (document, serialized, or raw). The first argument of the function is the key used to identify the result in the map return by the fn:transform function (for example, this will be the supplied base output URI in the case of the principal result, or the string "output" if no base output URI was supplied). The second argument is the actual value. The value that is returned in the result of the fn:transform function is the result of applying this post-processing.

    Note that neither fn:put nor the EXPath file module is provided by Saxonica's open-source Home Edition; there is a third party file module implementation on GitHub though: https://github.com/Armatiek/saxon-extensions