XPTY0004:'>'的第一个操作数的必需项类型是数字; 提供的值具有项类型xs:string

Vij*_*ayD 6 java xml xquery saxon xbrl

toComplie字符串包含函数的所有定义,如sum,multiply等附加 if ($a > 0) then (iaf:numeric-equal(iaf:numeric-multiply($b, $c), $d)) else (true())

执行此操作的代码段是:

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();
Run Code Online (Sandbox Code Playgroud)

抛出异常如下:

XPTY0004:'>'的第一个操作数的必需项类型是数字; 提供的值具有项类型xs:string


如果需要更多信息来了解这个问题,请告诉我.这是因为其他部分还是别的什么?

编辑:在setExternalVariables(),我使用for-each循环使用下面的行添加变量.value变量是类型net.sf.saxon.s9api.XdmValue

xqueryEvaluator.setExternalVariable(new QName(memberName), value);
Run Code Online (Sandbox Code Playgroud)

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));
Run Code Online (Sandbox Code Playgroud)

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();
Run Code Online (Sandbox Code Playgroud)

在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;
Run Code Online (Sandbox Code Playgroud)

当前的实现和替代(2)不适用于上面提到的规则,并且当我返回double时,它将大数字转换为包含char E的表达式,例如5.12344E12,其在其他规则中失败.

没有systemId模块的第199行出错:FORG0001:无法将字符串"1.089563E9"转换为xs:decimal:iaf处无效字符'E':splitValueThreshold()(没有systemId#20的模块)在iaf:numeric-equal( )(没有systemId#343的模块)

请建议任何其他选择.

Ghi*_*rny 1

我赞同 Martin 的建议(我首先忽略了 BigDecimal 与 BigDecimalValue)。

根据 Saxon 的文档,我还想到了一些替代方案:

atomicValue = new XdmAtomicValue(
    new BigDecimalValue(getDoubleValue(fact))
);
Run Code Online (Sandbox Code Playgroud)

或者避免使用双打或 BigDecimal,例如:

atomicValue = new XdmAtomicValue(
    (BigDecimalValue)BigDecimalValue.makeDecimalValue(getStringValue(fact), true)
);
// potentially adding an "instance of BigDecimalValue" check in the middle
// or bypassing all checks with 'false' instead of 'true'
Run Code Online (Sandbox Code Playgroud)

注意:我不确定我是否完全理解如果xs:double传递 an 而不是 则在其他规则中出现的问题xs:decimal。我怀疑可能会有一些回归参与这些其他规则,因为这是可以引入的xs:string地方。E任何类型的数值之间的 XPath 比较应该是无缝的。

一般来说(但我只是在这里猜测,因为除了在规则中看到 EBA 区间算术函数的使用之外,我不知道所涉及的细节),我认为对齐 XBRL 中使用或传递给 XBRL 的类型可能是一个好主意具有原始 XBRL 概念类型的公式规则(用于xs:decimal( xbrli:decimalItemTyper) 或xbrli:monetaryItemType(m),但xs:double用于xbrli:doubleItemType等),因为词汇空间将与 XBRL 实例中使用的词汇空间相匹配。