Forums » Saxon/C Help and Discussions »
Any working example of set_parameter on PyXPathProcessor?
Added by Martin Honnen about 5 years ago
Even after the fix on make_string_value
I am struggling to use a parameter in XPath evaluation in the Python API of Saxon/C 1.2.0 on Windows with Python 3.7.
The following program using XQuery runs fine now:
import saxonc
s1 = 'This is a test.'
with saxonc.PySaxonProcessor(license=False) as proc:
print(proc.version)
xdm_string_value = proc.make_string_value(s1)
print(xdm_string_value)
xquery_processor = proc.new_xquery_processor()
xquery_processor.set_parameter('s1', xdm_string_value)
result = xquery_processor.run_query_to_value(query_text = 'declare variable $s1 external; $s1')
print(result)
print(result.get_atomic_value().string_value)
However, the same code used with XPath crashes:
import saxonc
s1 = 'This is a test.'
with saxonc.PySaxonProcessor(license=False) as proc:
print(proc.version)
xdm_string_value = proc.make_string_value(s1)
print(xdm_string_value)
xpath_processor = proc.new_xpath_processor()
xpath_processor.set_parameter('s1', xdm_string_value)
result = xpath_processor.evaluate('$s1')
print(result)
print(result.get_atomic_value().string_value)
giving
Saxon/C 1.2.0 running with Saxon-HE 9.9.1.5J from Saxonica
This is a test.
JET RUNTIME HAS DETECTED UNRECOVERABLE ERROR: system exception at 0x00000000004546d6
Please, contact the vendor of the application.
I have tried to find a sample in the Python examples using set_parameter on an PyXPathProcessor but I can't find anything.
Replies (12)
Please register to reply
RE: Any working example of set_parameter on PyXPathProcessor? - Added by O'Neil Delpratt about 5 years ago
Yes there is still a bug here in the code. There is a segmentation error in RefCount method for the SaxonProcessor. I have created a new bug issue for this one: #4351
RE: Any working example of set_parameter on PyXPathProcessor? - Added by O'Neil Delpratt about 5 years ago
So I have managed to put some conditional statements in the evaluate method for both the C++ and Python code to check for when the underlying evaluate Java code is running NULL. Now I need to understand why the evaluate method is returning NULL. Perhaps the s1 parameter is not being set on the XPath query.
RE: Any working example of set_parameter on PyXPathProcessor? - Added by Martin Honnen about 5 years ago
I have now tried a similar code sample directly on the C++ side with
void testXPathStringParameter(SaxonProcessor * processor, XPathProcessor * xpath) {
cout << endl << "Test testXPathStringParameter:" << endl;
xpath->clearParameters(true);
xpath->clearProperties();
XdmAtomicValue *stringValue = processor->makeStringValue("This is a test.");
cout << "string parameter passsed to XPath: " << stringValue->getStringValue() << endl;
xpath->setParameter("s1", (XdmValue*)stringValue);
XdmItem *result = xpath->evaluateSingle("$s1");
if (result == NULL) {
printf("result is null \n");
}
else {
cout << "Number of items=" << result->size() << endl;
cout << "String Value of result=" << result->getStringValue() << endl;
}
delete result;
}
and the result
is NULL
.
Is the C++ API lacking a method to declare parameters for XPath evaluation, like http://saxonica.com/html/documentation/javadoc/net/sf/saxon/s9api/XPathSelector.html#setVariable-net.sf.saxon.s9api.QName-net.sf.saxon.s9api.XdmValue- on the Java side?
RE: Any working example of set_parameter on PyXPathProcessor? - Added by O'Neil Delpratt about 5 years ago
In the python script I added the following code to debug if we have any errors caught in Saxon/C:
if xpath_processor.exception_count() > 0:
print(xpath_processor.get_error_message(0)
Output in terminal:
net.sf.saxon.s9api.SaxonApiException : Undeclared variable in XPath expression: $s1
The XPathProcessor API for C++, Python and PHP does not have a declareVariable method as in the Java class XPathCompiler
. There is no real workaround for this issue. A fix will be in the next maintenance release.
RE: Any working example of set_parameter on PyXPathProcessor? - Added by O'Neil Delpratt about 5 years ago
The workaround would be to use the XQuery API.
RE: Any working example of set_parameter on PyXPathProcessor? - Added by Martin Honnen about 5 years ago
Well, I started with a working XQuery sample but in general, even if it allows me to pass in a variable, I don't get far with XQuery either, the following crashes:
import saxonc
n = 10
with saxonc.PySaxonProcessor(license=False) as proc:
print(proc.version)
xdm_int_value = proc.make_integer_value(n)
print(xdm_int_value)
xquery_processor = proc.new_xquery_processor()
xquery_processor.set_parameter('n', xdm_int_value)
result = xquery_processor.run_query_to_value(query_text = 'declare variable $n external; (1 to $n)!(. * .)')
print(result.size)
for i in range(result.size):
print(result.item_at(i))
Output:
Saxon/C 1.2.0 running with Saxon-HE 9.9.1.5J from Saxonica
10
1
JET RUNTIME HAS DETECTED UNRECOVERABLE ERROR: system exception at 0x0000000000428b82
I guess the whole stuff, at least propagating values from Saxon to Python, needs to mature a bit more.
Even without the use of set_parameter it crashes:
with saxonc.PySaxonProcessor(license=False) as proc:
print(proc.version)
xquery_processor = proc.new_xquery_processor()
result = xquery_processor.run_query_to_value(query_text = 'declare variable $n external := 10; (1 to $n)!(. * .)')
print(result.size)
for i in range(result.size):
print(result.item_at(i))
Or is that just a Windows issue?
RE: Any working example of set_parameter on PyXPathProcessor? - Added by O'Neil Delpratt about 5 years ago
I will investigate this in a separate bug issue. I think the issue of handling the memory of created XdmValue objects will take a few iterations to get right. Thank you for the feedback.
RE: Any working example of set_parameter on PyXPathProcessor? - Added by O'Neil Delpratt about 5 years ago
The issue is we are not handling properly the case where the `XdmValue is a sequence.
In the C++ code we are checking if the XdmValue is an instance of XdmNode
or XdmtomicValue
. But if it is neither of these types we just wrap the Java XdmValue object in the wrapper class in C++. This is no good in the case where the XdmValue
contains a sequence value like a SequenceExtent
object. In the Xslt30Processor object we handle this case by building sequence of items on the C++ side, but this code we are just not using in the XQueryProcessor
.
I have made the fix in the C++ code and the sample above works now. I will commit the patch to the C++ later today after I have done some more testing for you to try.
I initially thought this was a memory issue but this is not the case.
RE: Any working example of set_parameter on PyXPathProcessor? - Added by O'Neil Delpratt about 5 years ago
I have created the bug issue #4352 for keeping track of the progress.
RE: Any working example of set_parameter on PyXPathProcessor? - Added by O'Neil Delpratt about 5 years ago
Bug fixed and committed to subversion. Available in the next maintenance release, but can be applied by downloading the files mentioned in the bug issue #4352
RE: Any working example of set_parameter on PyXPathProcessor? - Added by Martin Honnen about 5 years ago
Great work, most stuff I have tried with the to_value
methods now works, what keeps from easily outputting a complete sequence with a direct print
is the issue in https://saxonica.plan.io/boards/4/topics/7610.
RE: Any working example of set_parameter on PyXPathProcessor? - Added by O'Neil Delpratt about 5 years ago
Martin Honnen wrote:
Great work, most stuff I have tried with the
to_value
methods now works, what keeps from easily outputting a complete sequence with a direct
The issue mentioned in the post https://saxonica.plan.io/boards/4/topics/7610 has now been fixed here #4352
Please register to reply