Thank you for your reply. In the example I compare a Number value with a String. "1" is a String, but "form('count')" returns an integer.
Here is the usage of Jaxen in our code.
A sample of XML code: <g:if test="form('campaignClone.uid') and form('orderClone.state') = '1'">
The code where XPath is called to evaluate whether the condition is true:
if ("if".equals(localName) && optimizeIf == 0 && !suspendOptimizeIf) {
try {
String value = attributes.getValue("test");
value = expandAVT(value, true, currentElement);
JDOMXPath path = new JDOMXPath(value);
path.setFunctionContext(xPathFunctions);
boolean ok = path.booleanValueOf(currentElement);
...
The variable "value" contains the String: "form('campaignClone.uid') and form('orderClone.state') = '1'"
xPathFunctions is an Instance of XPathFunctions, a subclass of FunctionContext. xPathFunctions defines how the condition is interpreted. form('orderClone.state') calls getOrderClone.getState
and form('campaignClone.uid') calls getCampaignClone.getUid of the corresponding form class.
public int getState()
{
return state;
}
public Long getUid()
{
return uid;
}
This condition is always false with the new version of Jaxen, because getState is an Integer and getUid is a Long value
We had to patch the NumberFunction so we could use Jaxen as usual.
Here is the code.
public static Double evaluate(Object obj, Navigator nav) {
if (obj instanceof Double)
{
return (Double) obj;
}
else if (obj instanceof Number)
{
return ((Number) obj).doubleValue();
}
else if (obj instanceof String) {
String str = (String) obj;
try
{
Double doubleValue = new Double(str);
return doubleValue;
}
catch (NumberFormatException e)
{
return NaN;
}
} else if (obj instanceof List || obj instanceof Iterator)
{
return evaluate(StringFunction.evaluate(obj, nav), nav);
} else if (nav.isElement(obj) || nav.isAttribute(obj)) {
return evaluate(StringFunction.evaluate(obj, nav), nav);
}
else if (obj instanceof Boolean) {
if (obj == Boolean.TRUE)
{
return new Double(1);
}
else
{
return new Double(0);
}
}
return NaN;
}
I think that this problem is a bug, because a Not a Number Exception for an Integer value is an unexpected behavior of a class called “NumberFunction”. A number function is expected to work with all kinds of numbers, especially integer and not only double and String. Otherwise it could be called “DoubleFunction”. This class indeed worked that way in the former version. When only doubles are used internally, other kind of numbers should be accepted and casted the same way it is done with Strings
It would be good when this issue would be solved, so we won't have to patch the class after every update of Jaxen.
I'll look into this. However it's not immediately apparent to me that this is a bug. XPath does not have an integer data type. All numbers in XPath are floating point, not integers:
http://www.w3.org/TR/xpath/#numbers
Do you have a test case that demonstrates the bug by evaluation of an XPath expression? (i.e. does not directly call the Number function in code). That would be more convincing.
In the example you cite I think you're actually comparing strings, not numbers. Try
<g:if test="form('count')=1">
instead and see if that works.