[SWS-640] evaluateAsBoolean returns true for node with text content "false" Created: 27/Aug/10  Updated: 04/May/12  Resolved: 01/Sep/10

Status: Closed
Project: Spring Web Services
Component/s: XML
Affects Version/s: 1.5.8
Fix Version/s: 2.0 RC1

Type: Bug Priority: Major
Reporter: David Judd Assignee: Arjen Poutsma
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: 0d
Time Spent: 2d 4h 29m
Original Estimate: Not Specified


 Description   

The method Jaxp13XPathTemplate.evaluateAsBoolean returns true if the element selected by the expression exists, regardless of its contents. The text contents can be empty, "false", or "WTF", and evaluateAsBoolean will return true.

This does not appear to match its Javadoc, which says: "Evaluates the given expression as a boolean. Returns the boolean evaluation of the expression, or false if it is invalid." The very similar method evaluateAsDouble has nearly identical Javadoc: "Evaluates the given expression as a double. Returns the evaluation of the expression, or Double.NaN if it is invalid." - but evaluateAsDouble returns the actual contents of the text node. If evaluateAsBoolean is really meant to mean, "doesExpressionSelectAnything", it should be renamed.

Below is a unit test that demonstrates the problem. The second assert fails.

The problem also occurs when using a WSDL which defines aFlag as type "xs:boolean". And, it also occurs with JaxenXPathTemplate. However, I have not seen it using sources other than DOMSource.

package com.yodle.misc;
 
import static org.junit.Assert.*;
 
import javax.xml.transform.dom.DOMSource;
 
import org.junit.Test;
import org.springframework.ws.server.endpoint.AbstractDomPayloadEndpoint;
import org.springframework.xml.transform.StringSource;
import org.springframework.xml.xpath.Jaxp13XPathTemplate;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
 
public class BugDemo {
 
	final String request =
		"<someRequest> " +		
		"	<aDouble>123</aDouble> " +
		"	<aFlag>false</aFlag> " +
		"</someRequest> ";
	
	private class Endpoint extends AbstractDomPayloadEndpoint {
 
		@Override
		protected Element invokeInternal(Element requestElement, Document responseDocument) throws Exception {
			Jaxp13XPathTemplate xPathTemplate = new Jaxp13XPathTemplate();
			DOMSource src = new DOMSource(requestElement);
			
			double aDouble = xPathTemplate.evaluateAsDouble("aDouble", src);
			assertEquals(123d, aDouble, 0.01);
			
			boolean aFlag = xPathTemplate.evaluateAsBoolean("aFlag", src);
			assertFalse(aFlag);
			
			return null;
		}
		
	};
	
	@Test
	public void demonstrateEvaluateAsBooleanStrangeBehavior() throws Exception {
		Endpoint endPoint = new Endpoint();
		endPoint.invoke(new StringSource(request));
	}
	
}



 Comments   
Comment by Arjen Poutsma [ 01/Sep/10 ]

Added formatting

Comment by Arjen Poutsma [ 01/Sep/10 ]

The return value of the evaluateAsBoolean method is determined per the boolean() function defined in the XPath specification. This means that an expression that selects zero nodes will return false, while an expression that selects one or more nodes will return true. An expression that returns a string returns false for empty strings and true for all other strings. An expression that returns a number returns false for zero and true for non-zero numbers.

I've cleared up the javadoc to make this clearer.

Comment by Arjen Poutsma [ 04/May/12 ]

Closing old issues

Generated at Mon Dec 11 15:24:10 UTC 2017 using JIRA 6.4.14#64029-sha1:ae256fe0fbb912241490ff1cecfb323ea0905ca5.