【发布时间】:2018-03-28 12:52:05
【问题描述】:
toComplie 字符串包含所有函数的定义,如 sum、multiply 等,由 if ($a > 0) then (iaf:numeric-equal(iaf:numeric-multiply($b, $c), $d)) else (true()) 附加
执行这个的sn-p是:
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();
抛出异常如下:
XPTY0004:'>'的第一个操作数的必需项类型是数字;提供的值具有项目类型 xs:string
如果需要更多信息来理解这个问题,请告诉我。这是因为其他部分,还是其他原因?
编辑:
在 setExternalVariables() 中,我使用 for-each 循环使用下面的行添加变量。 value 变量的类型为 net.sf.saxon.s9api.XdmValue
xqueryEvaluator.setExternalVariable(new QName(memberName), value);
在setExternalVariables()方法中,
// 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));
在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();
在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;
当前实现和替代(2)不适用于上述规则,当我返回双精度时,它将大数字转换为包含字符 E 的表达式,例如5.12344E12,在其他规则中失败。
没有 systemId 的模块的第 199 行出现错误: FORG0001:无法将字符串“1.089563E9”转换为 xs:十进制:无效字符“E” 在 iaf:splitValueThreshold()(没有 systemId 的模块#20) 在 iaf:numeric-equal() (没有 systemId 的模块#343)
请提出任何其他选择。
【问题讨论】:
-
嗯,你在哪里设置、构造或创建变量
value,你是想在那儿传入一个字符串还是某个数字类型? -
您可以使用saxonica.com/html/documentation/dotnetdoc/Saxon/Api/… 在您的Java 代码中构造一个
xs:decimal并将其传递给setExternalVariable。或者,您可以在 XPath 端使用if (xs:decimal($a) > 0) ...或按照答案建议使用if (number($a) > 0)...,尽管这会创建一个 xs:double。 -
抱歉,我想我发布了一个指向 .NET API 的链接,Java API 位于 saxonica.com/html/documentation/javadoc/net/sf/saxon/s9api/…。
-
如果你的 Java 代码中没有数字类型,而是一个字符串,那么你可以使用saxonica.com/html/documentation/javadoc/net/sf/saxon/s9api/… 来构造某个数字类型
-
@MartinHonnen,我无法将 if 条件更改为业务规则,所以我猜你的第二条评论不起作用。将检查您分享的链接是否有任何帮助!
标签: java xml xquery saxon xbrl