diff --git a/src/main/java/org/apache/commons/jxpath/ri/InfoSetUtil.java b/src/main/java/org/apache/commons/jxpath/ri/InfoSetUtil.java index a5f337034..ac273a69f 100644 --- a/src/main/java/org/apache/commons/jxpath/ri/InfoSetUtil.java +++ b/src/main/java/org/apache/commons/jxpath/ri/InfoSetUtil.java @@ -98,7 +98,7 @@ public static double doubleValue(final Object object) { return ((Number) object).doubleValue(); } if (object instanceof Boolean) { - return ((Boolean) object).booleanValue() ? 0.0 : 1.0; + return ((Boolean) object).booleanValue() ? 1.0 : 0.0; } if (object instanceof String) { if (object.equals("")) { diff --git a/src/test/java/org/apache/commons/jxpath/ri/compiler/CoreFunctionTest.java b/src/test/java/org/apache/commons/jxpath/ri/compiler/CoreFunctionTest.java index db68bde51..5b52dba36 100644 --- a/src/test/java/org/apache/commons/jxpath/ri/compiler/CoreFunctionTest.java +++ b/src/test/java/org/apache/commons/jxpath/ri/compiler/CoreFunctionTest.java @@ -114,6 +114,19 @@ void testCoreFunctions() { assertXPathValue(context, "round(2 div 0)", Double.valueOf(Double.POSITIVE_INFINITY)); } + @Test + void testBooleanToNumberConversionIsXPathConformant() { + // XPath number(true())=1 and number(false())=0; the numeric coercion used by arithmetic, + // relational operators and floor/ceiling/round must agree with number(), not invert it. + assertXPathValue(context, "$bool_true + 1", Double.valueOf(2)); + assertXPathValue(context, "$bool_false + 1", Double.valueOf(1)); + assertXPathValue(context, "floor($bool_true)", Double.valueOf(1)); + assertXPathValue(context, "ceiling($bool_false)", Double.valueOf(0)); + assertXPathValue(context, "round($bool_true)", Double.valueOf(1)); + assertXPathValue(context, "$bool_true > 0.5", Boolean.TRUE); + assertXPathValue(context, "$bool_false > 0.5", Boolean.FALSE); + } + @Test void testNumberConversionIsXPathConformant() { // Java number literals that are outside the XPath 1.0 number grammar must convert to NaN.