diff --git a/spring-integration-xml/src/main/java/org/springframework/integration/xml/router/XPathRouter.java b/spring-integration-xml/src/main/java/org/springframework/integration/xml/router/XPathRouter.java index 234237f75e..5c3a7ea09a 100644 --- a/spring-integration-xml/src/main/java/org/springframework/integration/xml/router/XPathRouter.java +++ b/spring-integration-xml/src/main/java/org/springframework/integration/xml/router/XPathRouter.java @@ -16,6 +16,7 @@ package org.springframework.integration.xml.router; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -45,7 +46,8 @@ public class XPathRouter extends AbstractMessageRouter { private final XPathExpression xPathExpression; private volatile XmlPayloadConverter converter = new DefaultXmlPayloadConverter(); - + + private volatile boolean evaluateAsNode = true; /** * Create a router that uses an XPath expression. The expression may @@ -95,6 +97,9 @@ public class XPathRouter extends AbstractMessageRouter { this.xPathExpression = expression; } + public void setEvaluateAsNode(boolean evaluateAsNode) { + this.evaluateAsNode = evaluateAsNode; + } /** * Specify the Converter to use when converting payloads prior to XPath evaluation. @@ -110,9 +115,14 @@ public class XPathRouter extends AbstractMessageRouter { @Override @SuppressWarnings("unchecked") - public List getChannelIdentifiers(Message message) { + protected List getChannelIdentifiers(Message message) { Node node = this.converter.convertToNode(message.getPayload()); - return this.xPathExpression.evaluate(node, this.nodeMapper); + if (this.evaluateAsNode){ + return this.xPathExpression.evaluate(node, this.nodeMapper); + } + else { + return Collections.singletonList((Object)this.xPathExpression.evaluateAsString(node)); + } } diff --git a/spring-integration-xml/src/test/java/org/springframework/integration/xml/router/XPathRouterTests.java b/spring-integration-xml/src/test/java/org/springframework/integration/xml/router/XPathRouterTests.java index 3ed037057c..3ee46b15a7 100644 --- a/spring-integration-xml/src/test/java/org/springframework/integration/xml/router/XPathRouterTests.java +++ b/spring-integration-xml/src/test/java/org/springframework/integration/xml/router/XPathRouterTests.java @@ -45,6 +45,30 @@ public class XPathRouterTests { assertEquals("Wrong number of channels returned", 1, channelNames.length); assertEquals("Wrong channel name", "one", channelNames[0]); } + + @Test + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void simpleSingleAttributeAsString() throws Exception { + Document doc = XmlTestUtil.getDocumentForString(""); + XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/@type"); + XPathRouter router = new XPathRouter(expression); + router.setEvaluateAsNode(false); + Object[] channelNames = router.getChannelIdentifiers(new GenericMessage(doc)).toArray(); + assertEquals("Wrong number of channels returned", 1, channelNames.length); + assertEquals("Wrong channel name", "one", channelNames[0]); + } + + @Test + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void simpleRootNode() throws Exception { + Document doc = XmlTestUtil.getDocumentForString("olegbang"); + XPathExpression expression = XPathExpressionFactory.createXPathExpression("name(./node())"); + XPathRouter router = new XPathRouter(expression); + router.setEvaluateAsNode(false); + Object[] channelNames = router.getChannelIdentifiers(new GenericMessage(doc)).toArray(); + assertEquals("Wrong number of channels returned", 1, channelNames.length); + assertEquals("Wrong channel name", "doc", channelNames[0]); + } @Test @SuppressWarnings({ "unchecked", "rawtypes" }) @@ -57,16 +81,24 @@ public class XPathRouterTests { assertEquals("Wrong channel name", "bOne", channelNames[0]); assertEquals("Wrong channel name", "bTwo", channelNames[1]); } + @Test @SuppressWarnings({ "unchecked", "rawtypes" }) + /* + * Will return only one (the first node text in the collection), since + * the evaluation return type use is String (not NODESET) + * This test is just for sanity and the reminder that setting 'evaluateAsNode' + * to 'false' would still result in no exception but result will most likely be + * not what is expected. + */ public void multipleNodeValuesAsString() throws Exception { XPathExpression expression = XPathExpressionFactory.createXPathExpression("/doc/book"); XPathRouter router = new XPathRouter(expression); + router.setEvaluateAsNode(false); Object[] channelNames = router.getChannelIdentifiers(new GenericMessage("bOnebTwo")).toArray(); - assertEquals("Wrong number of channels returned", 2, channelNames.length); + assertEquals("Wrong number of channels returned", 1, channelNames.length); assertEquals("Wrong channel name", "bOne", channelNames[0]); - assertEquals("Wrong channel name", "bTwo", channelNames[1]); } @Test(expected = MessagingException.class)