'SaxonC 11.1 transform_to_file Produces No Output File

Using SaxonC-HE 11.1 in Python3 to transform XML into a new file appears to produce no file. Here's the py code:

import os
import saxonc
    
with saxonc.PySaxonProcessor(license=True) as saxonproc:
   xsltproc = saxonproc.new_xslt30_processor()
   saxonproc.set_cwd(os.getcwd())
   out = xsltproc.transform_to_file(source_file="in.xml", stylesheet_file="test.xsl", output_file="out.xml")
   print(out)
   out_contents = saxonproc.parse_xml(xml_file_name="out.xml")
   print(out_contents)

The associated XML file contents are:

in.xml:

<?xml version="1.0" encoding="UTF-8"?>
<in/>

test.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'>
<xsl:output method='xml' indent='yes' />

   <xsl:template match='*'>
      <xsl:message>Here!</xsl:message>
      <out/>
   </xsl:template>
</xsl:stylesheet>

The transform_to_file method does… nothing. No output file is created (and I've looked through the entire drive for out.xml!). Correction: it does generate the output file in the root drive location (in this case, D:), despite setting the cwd. The print() commands return NONE in the console.

Note: the xsl:message is just used as a check to verify the transformation is happening, and this does produce the message in my output console. But there is no statement back from SaxonC that any transformation is happening (as does occur with the workaround I have below).

My current workaround is to use the transform_to_string method and then just write the results to an XML file, which appears to work without issues. This gives an output statement in the console from SaxonC: "source in transformFiletoString=in.xml stylsheet=test.xsl" along with my message from the XSLT file.

import os
import saxonc

with saxonc.PySaxonProcessor(license=True) as saxonproc:
   xsltproc = saxonproc.new_xslt30_processor()
   saxonproc.set_cwd(os.getcwd())
   out = xsltproc.transform_to_string(source_file="in.xml", stylesheet_file="test.xsl")
   with open("out.xml", "w") as f:
     f.write(out)
   print(out)
   out_contents = saxonproc.parse_xml(xml_file_name="out.xml")
   print(out_contents)

It's not an impediment to my work, but it sure seems like an unnecessary step when SaxonC apparently should have the ability to write directly to a file. There has to be something simple I'm missing but so far, I simply cannot get transform_to_file to produce any file or output at all.



Solution 1:[1]

The cwd just needs to be set before the xslt processor. The following generates the output file as expected:

import os
import saxonc

with saxonc.PySaxonProcessor(license=True) as saxonproc:
 saxonproc.set_cwd(os.getcwd()) #set the CWD first
 xsltproc = saxonproc.new_xslt30_processor()
 xsltproc.transform_to_file(source_file="in.xml", stylesheet_file="test.xsl", output_file="out.xml")
 out_contents = saxonproc.parse_xml(xml_file_name="out.xml")
 print(out_contents)

Solution 2:[2]

Additional note: In order to make the transform_to_file() method work, it's also important to always supply a source file by the source_file keyword, rather than supplying a PyXdmNode in the xdm_node argument. This is confusing, because the documentation stated wrongly that you could give such an argument, while the function actually doesn't take PyXdmNodes and therefore won't perform any transformation due to lack of input. In some old distributions of SaxonC the documentation might still be wrong. See the corresponding Saxonica Issue: https://saxonica.plan.io/issues/5446

(I know that the original question didn't involve this keyword problem. But since I came to this post with the exact same problem as the question owner and setting the cwd alone didn't work for me because I was using the wrong keyword, I hope it's ok that I comment on this pitfall in case others might have the same problem and land here as I did.)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jason Coleman
Solution 2 AlinaOs