Project

Profile

Help

How to pass parameters to Saxon/C

Added by santanu das about 2 years ago

Hi,

I'm using SaxonHE/C 1.2.1 and SaxonEE/C 1.2.1. Below is my code written in Python 3.7:

import saxonc proc = saxonc.PySaxonProcessor(license=True, config_file=config_file_path) proc.set_catalog(transform_details['catalog_path']) xsltproc = proc.new_xslt_processor() xsltproc.set_property('im', 'transform') output = xsltproc.transform_to_file(source_file=transform_details['input_file_location'] + '/input.xml', stylesheet_file=transform_details['script'], output_file=transform_details['output_file_location'] + '/output.xml')

But it's not generating any output. When I'm using 'saxon.jar' with PHP with the same resource files it is generating output.

Please let me know how to pass information like: '-im:transform LOGLEVEL=20'

If I want to pass any associated list of files to xsltproc then how to do that?

Do we need to set '-o' and '-s' in the above coding structure?

Please guide me.

Thanks, Santanu


Replies (23)

Please register to reply

RE: How to pass parameters to Saxon/C - Added by O'Neil Delpratt about 2 years ago

Hi,

Do you have a complete repo that I can run at my end please?

RE: How to pass parameters to Saxon/C - Added by santanu das about 2 years ago

Hi,

I'm using SaxonHE/C 1.2.1 and SaxonEE/C 1.2.1. Below is my code written in Python 3.7:

import saxonc 
proc = saxonc.PySaxonProcessor(license=True, config_file=config_file_path) 
proc.set_catalog(transform_details['catalog_path']) 
xsltproc = proc.new_xslt_processor()
xsltproc.set_property('im', 'transform') 
output = xsltproc.transform_to_file(source_file=transform_details['input_file_location'] + '/input.xml', 
                                                          stylesheet_file=transform_details['script'], 
                                                          output_file=transform_details['output_file_location'] + '/output.xml')

But it's not generating any output. When I'm using 'saxon.jar' with PHP with the same resource files it is generating output.

Please let me know how to pass information like: '-im:transform LOGLEVEL=20'

If I want to pass any associated list of files to xsltproc then how to do that?

Do we need to set '-o' and '-s' in the above coding structure?

How to display what are the final information passed to xsltproc object?

Please guide me.

Thanks, Santanu

RE: How to pass parameters to Saxon/C - Added by santanu das about 2 years ago

Hi Neil,

Thanks for your reply. Do you think my code is good enough to parse a xml file with an xslt script? The methods are correctly written?

Means, if '-im:transform LOGLEVEL=20' is correctly set or do we need to set '-o' and '-s' in the above coding structure.

Actually I'm using client resources so can't pass those outside.

Thanks, Santanu

RE: How to pass parameters to Saxon/C - Added by O'Neil Delpratt about 2 years ago

Hi Santanu,

Thanks for update to the code. The formatting helps. Is it possible to send it privately via email? Or at least a modified repo that shows the failure. Also do you have a copy of the catalog file.

RE: How to pass parameters to Saxon/C - Added by O'Neil Delpratt about 2 years ago

Are you saying the file: output_file=transform_details['output_file_location'] + '/output.xml' is not created?

Just looking at your python code again. transform_to_file does not return a result, but results the result into the file. Hence the output variable is not needed.

Is it possible you can try @transform_to_sting@ and print the result just to narrow down the problem.

RE: How to pass parameters to Saxon/C - Added by santanu das about 2 years ago

Hi Neil,

Here is my modified code:

output = xsltproc.transform_to_string(source_file=transform_details['input_file_location'] + '/input.xml', 
                                                          stylesheet_file=transform_details['script'])

Now it's giving me the error "'utf-8' codec can't decode byte 0xed in position 1341: invalid continuation byte"

How to fix that?

Couple of questions:

  1. How to output the results in a output file? Do I need to do simple file handling code? I can see in your example:
xsltproc.transform_to_file(source_file="cat.xml", stylesheet_file="test1.xsl", output_file="result.xml")

How 'output_file' is used with 'transform_to_file' method here?

  1. When we use Saxon.jar in PHP we don't need to pass any named input file instead we provide only the input folder path and it works. But incase of Saxon/C Python module we need to provide a named input file. Is there any technique where passing only the input folder path is enough?

  2. xsltproc.set_property('im', 'transform') Is it a correct way to pass '-im:transform LOGLEVEL=20' ?

Correct me if I am wrong.

Thanks, Santanu

RE: How to pass parameters to Saxon/C - Added by O'Neil Delpratt about 2 years ago

santanu das wrote:

Here is my modified code:

output = xsltproc.transform_to_string(source_file=transform_details['input_file_location'] + '/input.xml', 
                                                          stylesheet_file=transform_details['script'])

Now it's giving me the error "'utf-8' codec can't decode byte 0xed in position 1341: invalid continuation byte"

How to fix that?

This is a bug in the API where we are not encoding the string correctly. We have resolved this bug in the soon to be release. I am wondering if the same issue happens if you use the PyXslt30Processor class instead of the older PyXsltProcessor class:

import saxonc 
proc = saxonc.PySaxonProcessor(license=True, config_file=config_file_path) 
proc.set_catalog(transform_details['catalog_path']) 
xsltproc = proc.new_xslt30_processor()
xsltproc.set_property('im', 'transform') 
output = xsltproc.transform_to_string(source_file=transform_details['input_file_location'] + '/input.xml', 
                                                          stylesheet_file=transform_details['script'])

print(result)

For outputting to file you would do the following:

xsltproc.transform_to_file(source_file=transform_details['input_file_location'] + '/input.xml', stylesheet_file=transform_details['script'], output_file=transform_details['output_file_location'] + '/output.xml')

Couple of questions:

  1. How to output the results in a output file? Do I need to do simple file handling code? I can see in your example:
xsltproc.transform_to_file(source_file="cat.xml", stylesheet_file="test1.xsl", output_file="result.xml")

How 'output_file' is used with 'transform_to_file' method here?

The value for the keyword output-file is the file name.

  1. When we use Saxon.jar in PHP we don't need to pass any named input file instead we provide only the input folder path and it works. But incase of Saxon/C Python module we need to provide a named input file. Is there any technique where passing only the input folder path is enough?

I see there is a difference in behaviour on Java command when a directory is supplied. I will investigate the further. Are you running some Java Jar file on PHP in some special way? I guess this is not Saxon/C PHP extension.

  1. xsltproc.set_property('im', 'transform') Is it a correct way to pass '-im:transform LOGLEVEL=20' ?

Yes, this does look correct. But the parameter LOGLEVEL=20 is not being captured. If this is important you can use set_initial_template_parameters

RE: How to pass parameters to Saxon/C - Added by O'Neil Delpratt about 2 years ago

The Xslt30Processor has a patch which you can apply by replacing the following file Xslt30Processor.cpp: https://saxonica.plan.io/attachments/49176

See bug issue: https://saxonica.plan.io/issues/4847

RE: How to pass parameters to Saxon/C - Added by santanu das about 2 years ago

Hi Neil,

Thanks for your time.

  1. I'm using PyXsltProcessor to parse xml files with 'version="1.0"'. Like '<?xml version="1.0" encoding="UTF-8"?>'. PyXslt30Processor is required to parse xml files with version="3.0". Is it possible to use PyXslt30Processor to parse xml with version=1.0 ?

  2. I'm using the same code structure like you mentioned for transform_to_file:

xsltproc.transform_to_file(source_file=transform_details['input_file_location'] + '/input.xml', 
                                                          stylesheet_file=transform_details['script'], 
                                                          output_file=transform_details['output_file_location'] + '/output.xml')

But it's not creating any file or showing any error.

  1. I'm running Java commands from PHP and using saxon.jar like the following way:

net.sf.saxon.Transform -r:org.apache.xml.resolver.tools.CatalogResolver -x:org.apache.xml.resolver.tools.ResolvingXMLReader -dtd:off -strip:none -expand:off -xsl:'/script.xsl'....

This is not a Saxon/C PHP extension. Our business requirement is to pass only the input and output directory because there used to be multiple input files and multiple output files in a workflow. Kindly have a look on how to do that in Saxon/C Python extension.

  1. How to display what are the final information passed to xsltproc object? Like in PHP or Python we can print an object to see it's current status.

Thanks, Santanu

RE: How to pass parameters to Saxon/C - Added by santanu das about 2 years ago

Hi Neil,

Please find the attached source xml and xslt script. Please run those files with 'Saxon/C 1.2.1 with Saxon-EE 9.9.1.5C' from your end and see if the 'transform_to_file' is able to create an output file. It requires one parameter 'insert="Hello World"'.

Below is my code:

import saxonc
proc = saxonc.PySaxonProcessor(license=True)
	xsltproc = proc.new_xslt_processor()
	xsltproc.set_parameter('insert', proc.make_string_value('Hello World'))
	xsltproc.transform_to_file(source_file='/tmp/sample-xslt-unzip/Sample1.xml',
								stylesheet_file='/tmp/sample-xslt-unzip/Script1.xsl',
								output_file='/tmp/output.xml')

Thanks, Santanu

RE: How to pass parameters to Saxon/C - Added by O'Neil Delpratt about 2 years ago

Thank you for this. I will investigate it further and respond.

Just to answer your previous question you can use the PyXslt30Processor class for XSLT 1.0 stylesheets which is executed in backward compatibility mode.

RE: How to pass parameters to Saxon/C - Added by santanu das about 2 years ago

Hi Neil,

Is there any update on passing only the input/output directory path instead passing the named input/output file? We are using Saxon/C 1.2.1 licensed version. It's our business requirement.

Thanks, Santanu

RE: How to pass parameters to Saxon/C - Added by O'Neil Delpratt about 2 years ago

Hi Santanu,

Yes sure. Apologies for the delay.

RE: How to pass parameters to Saxon/C - Added by O'Neil Delpratt about 2 years ago

Hi Santanu,

I ran your program with Saxon/C 1.2.1 and the pre-release SaxonC 11.1 and both outputs the output.xml file in the /tmp location on my machine as expected.

I am wondering if you have some permission issue? Maybe we can have a screen share and you can demonstrate the issue.

RE: How to pass parameters to Saxon/C - Added by O'Neil Delpratt about 2 years ago

Just to add, when I run the command:

more /tmp/output.xml

I see the content of the file as below:

<?xml version="1.0" encoding="UTF-8"?><main><metadata>Metadata goes here.</metadata>
    <div>
        <title type="Hello World">Title1</title>
        <p>This is some content.</p>
    </div>
</main>

RE: How to pass parameters to Saxon/C - Added by santanu das about 2 years ago

Hi Neil,

I was able to output file using PyXslt30Processor but not PyXsltProcessor. If PyXslt30Processor is able to work in backward compatibility mode then it's fine to use PyXslt30Processor.

Now the main concern how to pass only the input/output directory path and not the named input/output files. Because in our functionality there could be multiple input and output files.

Please add this support for Saxon/C. Let me know.

Thanks, Santanu

RE: How to pass parameters to Saxon/C - Added by O'Neil Delpratt about 2 years ago

Please can you send me another example program which shows up the problem. Thanks

RE: How to pass parameters to Saxon/C - Added by santanu das about 2 years ago

Hi Neil,

I think if you omit the input and output file name from the paths it won't work. I've already tested. You only need to specify the directory path, like

source_file='/tmp/sample-xslt-unzip/'
output_file='/tmp/'

Thanks, Santanu

RE: How to pass parameters to Saxon/C - Added by O'Neil Delpratt about 2 years ago

I have discussed your requirement for functionality for multiple input and output files on a directory. This feature is only available in the command-line application, there you cannot do it via any of the APIs across all languages.

As a workaround there are two possibilities:

  1. Add some Python code to traverse over the files in a directory and execute the XSLT transformation for each file it finds. The output can then be saved to file.

  2. Modify your stylesheet to use the fn:collection() function for the directory of files you want as input. See: Directory: https://www.saxonica.com/html/documentation11/sourcedocs/collections/collection-directories.html

Also see: https://www.saxonica.com/html/documentation11/sourcedocs/collections/

RE: How to pass parameters to Saxon/C - Added by santanu das about 2 years ago

Hi Neil,

Is there a chance to add the directory path feature in Saxon/C api in near future?

Thanks, Santanu

RE: How to pass parameters to Saxon/C - Added by O'Neil Delpratt about 2 years ago

We have added it to the future requirements list.

RE: How to pass parameters to Saxon/C - Added by santanu das about 2 years ago

Hi Neil,

If you don't mind, may I know if there is any specific timeline? Asking because we can arrange our developments accordingly.

Thanks, Santanu

RE: How to pass parameters to Saxon/C - Added by O'Neil Delpratt about 2 years ago

Hi,

This feature we hope will be in the next major release. The general pattern of major releases is anything from 1-2 years. I hope that helps

Kind regards,

O'Neil

    (1-23/23)

    Please register to reply