ph-schematron icon indicating copy to clipboard operation
ph-schematron copied to clipboard

Variables are not always resolved to the correct type in pure mode

Open bertrand-lorentz opened this issue 9 months ago • 0 comments

Following the change I proposed in PR #164, I've noticed that in certain cases, when the variable value is evaluated in the let statement, the result is not in the expected type.

For example:

    <let name="stringVar" value="'foo'"/>
    <rule context="/*">
      <assert role="ERROR" test="$stringVar eq 'bar'">error message</assert>
    </rule>

Fails with the error: Failed to evaluate XPath expression to a boolean: '$stringVar eq 'bar'' (net.sf.saxon.trans.XPathException: Values are not comparable (xs:boolean, xs:string))"

And:

    <let name="booleanVar" value="1 eq 1"/>
    <rule context="/*">
      <assert role="ERROR" test="$booleanVar eq true()">error message</assert>
    </rule>

Fails with the error: Failed to evaluate XPath expression to a boolean: '$booleanVar eq true()' (net.sf.saxon.trans.XPathException: Values are not comparable (xs:double, xs:boolean))"

This is because in PSXPathBoundSchema._evaluateVariables(), we try to evaluate the variable with each possible return type (NodeList, Boolean, String, etc.) one after the other, and stop at the first that doesn't throw an Exception.

I don't think there's a specific order of return types that would work in all cases. For example, a number can be evaluated as a boolean, and a boolean can be evaluated as a number.

It would be nice to have a way the evaluate an XPath without specifying (or implying) the return type, but that does not exist for javax.xml.xpath.XPathExpression.evaluate(). I've tried also with XPathExpression.evaluateExpression() but it does not seem to work.

The custom API in Saxon (s9api) does seem to offer this option: https://www.saxonica.com/documentation12/index.html#!xpath-api/s9api-xpath But I guess this comes with its own challenges...

Any ideas or suggestions on how to tackle this are welcome !

bertrand-lorentz avatar May 24 '24 09:05 bertrand-lorentz