The toComplie string contains all the definitions of the functions like sum, multiply, etc. appended by if ($a > 0) then (iaf:numeric-equal(iaf:numeric-multiply($b, $c), $d)) else (true())
The snippet executing this is :
XQueryExecutable queryExecutable = xqueryCompiler.compile(toCompile.toString());
XQueryEvaluator xqueryEvaluator = queryExecutable.load();
//setExternalVariables(): function used to set the variables for the test contains below line
xqueryEvaluator.setExternalVariable(new QName(memberName), value);
setExternalVariables(xqueryEvaluator,assertionExpression);
xqueryResult = xqueryEvaluator.evaluate();
Which throws an exception as below:
XPTY0004: Required item type of the first operand of '>' is numeric; supplied value has item type xs:string
Please let me know if any more information is needed to understand the question. Is this because of the else part, or something else?
EDIT:
In setExternalVariables()
, I'm adding the variables using below line, using for-each loop. value
variable is of type net.sf.saxon.s9api.XdmValue
xqueryEvaluator.setExternalVariable(new QName(memberName), value);
In setExternalVariables()
method,
// FACT_VALUE_FORMAT:%s;%s -- where first string is value and second gives information about precision.
//current option
XdmAtomicValue atomicValue = new XdmAtomicValue(String.format(FACT_VALUE_FORMAT, fact.getValue(),getPrecision(fact.getDecimals())));
// alternative 1
atomicValue = new XdmAtomicValue(getDoubleValue(fact));
//alternative 2
atomicValue = new XdmAtomicValue(getStringValue(fact));
In getDoubleValue()
,
String precision = fact.getDecimals();
BigDecimal value = new BigDecimal(fact.getValue());
if((precision != null ) && (precision.equals(INF_STRING) == false )){
if(Integer.parseInt(precision)>0){
NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
DecimalFormat df = (DecimalFormat)nf;
// If the decimal value is greater than 0, then we need the decimal precision correct to n places of decimal
df.setMaximumFractionDigits(Integer.parseInt(precision) + 1);
double doublePrecision = Math.pow(10,-Integer.parseInt(precision))/2;
df.setMaximumFractionDigits(Integer.parseInt(precision) + 1);
precision = df.format(doublePrecision);
System.out.println("doublePrecision\t:\t"+doublePrecision);
return (double) Math.round(value.doubleValue() * doublePrecision) / doublePrecision;
}else{
int scale = (int) Math.pow(10, -Integer.parseInt(precision));
System.out.println("scale\t:\t"+scale);
return (double) Math.round(value.doubleValue() * scale) / scale;
}
}
return value.doubleValue();
In getStringValue(),
String value = fact.getValue();
String decimal = fact.getDecimals();
String DOT = "\\.";
if(value.contains(".")){
final int parseInt = Integer.parseInt(decimal);
if(parseInt>0){
String[]split = value.split(DOT);
value = split[0];
if(parseInt>=value.length()){
return "0";
}
for (int i = 0; i < parseInt; i++) {
char[] array =value.toCharArray();
array[value.length()-i-1]="0".charAt(0);
value = new String(array);
}
}else{
final int parseNegativeInt = -Integer.parseInt(decimal);
String[]split = value.split(DOT);
String tempValue = split[1];
if(tempValue.length()>parseNegativeInt){
tempValue = tempValue.substring(0, parseNegativeInt);
}
value = split[0]+"."+tempValue;
}
}
return value;
Current implementation and alternative(2) does not work for the rule mentioned above, and when I'm returning double, it transforms big numbers into expression containing char E, for e.g. 5.12344E12, which fails in other rules.
Error on line 199 of module with no systemId: FORG0001: Cannot convert string "1.089563E9" to xs:decimal: invalid character 'E' at iaf:splitValueThreshold() (module with no systemId#20) at iaf:numeric-equal() (module with no systemId#343)
Please suggest any other option.
Typically XPath >
implicitly converts a string operand to a number, but you can force the conversion using the number()
XPath function.
if (number($a) > 0) then (iaf:numeric-equal(iaf:numeric-multiply($b, $c), $d)) else (true())
Assuming you have your numeric values on the Java side as Strings in e.g. String value = "2179.125955";
then I would suggest to pass them as xs:decimal
s to XQuery/XPath by using new XdmAtomicValue(new BigDecimal(value))
as the value you pass to setExternalVariable
e.g.
xqueryEvaluator.setExternalVariable(new QName(memberName), new XdmAtomicValue(new BigDecimal(value)));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With