I managed to reproduce the error message and it is bug.
The problem is the return type used in the internal JNI method signature in the C++ code is wrong. The bug has been fixed in a redesign of the xsl:message mechanism to make it more usable. This will be available in the next release, but as I workaround see below.
In the method getXslMessage
of the class file Xslt30Processor.cpp
we currently have the following:
jmethodID mID = (jmethodID) SaxonProcessor::sxn_environ->env->GetMethodID(cppClass,
"getXslMessages",
"()[Lnet/sf/saxon/s9api/XdmValue;");
Please replace it with the following:
jmethodID mID = (jmethodID) SaxonProcessor::sxn_environ->env->GetMethodID(cppClass,
"getXslMessages",
"()[Lnet/sf/saxon/s9api/XdmNode;");
I have also attached the file to this bug with the patch so you can just drop and replace the file if that is easier. Then rebuild the Saxon/C python extension again.
What actually happens to the xsl:messages by default is to output messages to the standard output console, but this does not find its way to python. As mentioned in the bug issue #4147 to capture the messages you will have to call xsltproc.set_property('m', '')
before you do the transformation. See example python code below which should work for you:
xsltproc = proc.new_xslt30_processor()
xsltproc.set_property('m', '') #This flag creates a Message Listener which intercepts the messages to return `PyXdmNode` objects of the messages
outputi = xsltproc.transform_to_string(source_file="source.xml", stylesheet_file="style.xsl")
print(outputi) #This Works
messages = xsltproc.get_xsl_messages()
if messages is not None:
i = 0
while i < messages.size:
print(messages.item_at(i))
i += 1
The get_xsl_message
returns an PyXdmValue
of the individual messages which are PyXdmNode
objects.
The PyXdmValue should be iterable. I will create another bug issue for this.