Issue: Trying to build the correct XPATH using SpEL xpath to correlate on a the "Name" tag value where the root tag has a namespace but no prefix.
Error: Unexpected token. Expected 'rparen())' but was 'identifier' It's complaining about & #39; where I am trying to make a single quote for the xpath evaluation.
XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xmlns="http://www.foo.com">
<id></id>
<Name>test</Name>
</root>
Spring Config
<aggregator
id="agg1"
input-channel="requestChannel"
output-channel="outputChannel"
discard-channel="garbageCanChannel"
ref="blah"
method="combine"
expire-groups-upon-completion="true"
correlation-strategy-expression="#xpath(payload, '//*[local-name()]='Name'/text()')"
release-strategy="blah"
release-strategy-method="timeToRelease"
send-partial-result-on-expiry="false"
send-timeout="60000"
group-timeout="60000"
/>
Update:
So after downloading spring source and tracing the issue. It's seem that during the tokenization execution in the method below, Spring is treating the "Name" as a identifier instead of as part of the string literal. At least this is the difference between a working instance and a failing instance.Most likely i'm not escaping it correctly.
Class:InternalSpelExpressionParser.java Method:doParseExpression
this.expressionString = "#xpath(payload, '//*[local-name()=Name]')"//This works
[[HASH(#)](0,1), [IDENTIFIER:xpath](1,6), [LPAREN(()](6,7), [IDENTIFIER:payload](7,14), [COMMA(,)](14,15), [LITERAL_STRING:'//*[local-name()=Name]'](16,45), [RPAREN())](45,46)]
this.expressionString = "#xpath(payload, '//*[local-name()='Name']')"//Thisfails
[[HASH(#)](0,1), [IDENTIFIER:xpath](1,6), [LPAREN(()](6,7), [IDENTIFIER:payload](7,14), [COMMA(,)](14,15), [LITERAL_STRING:'//*[local-name()='](16,35), [IDENTIFIER:Name](35,44), [LITERAL_STRING:']'](44,47), [RPAREN())](47,48)]
Solution: ...
correlation-strategy-expression="#xpath(payload, '//*[local-name()=''Name'']/text()')"
Correct String Literal: -You can see that it is now correct because the tokenization process is putting everything within the string literal token.
[[HASH(#)](0,1), [IDENTIFIER:xpath](1,6), [LPAREN(()](6,7), [IDENTIFIER:payload](7,14), [COMMA(,)](14,15), [LITERAL_STRING:'//*[local-name()=''Name'']/text()'](16,56), [RPAREN())](56,57)]
Additional Debug Notes:
When pulling out the spring git here:
https://github.com/spring-projects/spring-framework
Your expression as posted will produces invalid XPath. It should have closing square bracket just before /text()
instead :
'//*[local-name()='Name']/text()'
Or maybe using double single-quotes to escape, as suggested here :
'//*[local-name()=''Name'']/text()'