Bug #5849
closedtransform_to_file() in PyXslt30Processor not working.
100%
Description
Using Saxon 12 (installed w/pypi) on Python 3.8.
transform_to_file()
seems to try to use the output file as input.
If I try the following python without an existing output file "simple_output.xml":
from saxonche import *
def run():
with PySaxonProcessor(license=False) as proc:
print(f"Processor version: {proc.version}")
xsltproc = proc.new_xslt30_processor()
xsltproc.transform_to_file(source_file=r"try_saxon_input.xml",
stylesheet_file=r"simple.xsl",
output_file=r"simple_output.xml")
for x in range(0, 3):
run()
I get the following console output (I get this 3 times, but only including once for brevity. Also, I'm running this in PyCharm.):
Processor version: SaxonC-HE 12.0 from Saxonica
Error
I/O error reported by XML parser processing simple_output.xml. Caused by
java.io.FileNotFoundException: C:\Users\Dan Haley\Desktop\try_saxon\simple_output.xml (The
system cannot find the file specified)
If I create a file named "simple_output.xml" with the content <foo/>
, I don't get an exception but this is what "simple_output.xml" looks like:
<foo processed="1 2 3"/>
So it appears it's using the output as input.
Here's my XSLT if needed to reproduce:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" expand-text="yes">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="/*">
<xsl:copy>
<xsl:attribute name="processed" select="let $tokens := tokenize(@processed)
return string-join(($tokens,count($tokens)+1),' ')"/>
<xsl:apply-templates select="@* except @processed|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
As a work-around, I'm first compiling the stylesheet and using the transform_to_file()
method from PyXsltExecutable.
Files
Updated by O'Neil Delpratt almost 2 years ago
Thanks for reporting this issue and sending us the repo. I managed to reproduced the problem and investigating it now.
As a workaround I was able to get the correct output using the PyXsltExecutable which is also recommended as a feature rich XSLT 3.0 API instead of executing the stylesheets with the 'one-shot' methods on the PyXsltTransformer:
from saxonche import *
def run():
with PySaxonProcessor(license=False) as proc:
print(f"Processor version: {proc.version}")
xsltproc = proc.new_xslt30_processor()
executable = xsltproc.compile_stylesheet(stylesheet_file=r"simple.xsl")
executable.apply_templates_returning_file(source_file=r"try_saxon_input.xml", output_file=r"simple_output.xml")
for x in range(0, 3):
run()
This gave me the output:
<?xml version="1.0" encoding="UTF-8"?>
<doc processed="1" attr="some attr"><?pi test?>
<test>This <x>is</x> a test.</test>
<!--comment test-->
<ol>
<li>one</li>
<li>two</li>
<li>three</li>
</ol>
</doc>
Updated by Daniel Haley almost 2 years ago
Thanks O'Neil. I'm also able to use the .transform_to_file()
method from the PyXsltExecutable.
Is there any reason to use .apply_templates_returning_file()
over .transform_to_file()
?
Thanks again!
Updated by O'Neil Delpratt almost 2 years ago
Oh yes I forgot about transform_to_file
. You can use that method.
The apply_templates_returning_file
does not set the global context item for the transformation. If that is required use the transform_to_file
or call set_global_context_item
before calling apply_templates_returning_file
.
Updated by O'Neil Delpratt over 1 year ago
- Category set to Python API
- Status changed from New to Resolved
- Assignee set to O'Neil Delpratt
- % Done changed from 0 to 100
- Found in version set to 12.0
This bug issue has been resolved. The PyXslt30Processor.transform_to_file has now been corrected and tested.
Fix available in the next maintenance release.
Updated by O'Neil Delpratt over 1 year ago
- Status changed from Resolved to Closed
- Fixed in version set to 12.1
Bug fixed applied in the SaxonC 12.1 maintenance release.
Please register to edit this issue