I've got a simple flow, it takes an XML messages, splits it into sub elements and now I am trying to get a value, but getting unexpected results.
My XML looks like this:
<?xml version="1.0" encoding="UTF-8" ?>
<ns0:RewardOfferDetail xmlns:ns0="http://example.com/schemas/v1_0/RewardOffer">
<ns0:Offer>
<ns0:OperationCode>U</ns0:OperationCode>
</ns0:Offer>
<ns0:Offer>
<ns0:OperationCode>A</ns0:OperationCode>
</ns0:Offer>
</ns0:RewardOfferDetail>
I need to extract the <OpeartionCode>
from each <Offer>
The split works fine, and when I log out the payload after the split, it is a <Offer>
just fine. but then I try to extract the value of <OperationCode>
using this:
#[xpath('/rewardsns:Offer/rewardns:OperationCode')]
I get nothing, just a null value, then I try using a broader xpath expression:
#[xpath('//rewardns:OperationCode')]
And the result is two nodes, which leads me to believe that the xpath function is not looking at the right spot. but I've even trying telling it where to look and still no luck.
#[xpath('//rewardns:OperationCode', message.payload)]
#[xpath('//rewardns:OperationCode', payload)]
still yields two nodes.
Any Suggestions?
Flow:
<flow name="receiveMessageFlow">
<jms:inbound-endpoint
queue="#{loyaltySettings.getString('loyalty.queue.receive')}"
connector-ref="jmsConnector" doc:name="Loyalty Queue" />
<message-filter doc:name="XSD Validation" onUnaccepted="invalidXmlMessage">
<filter ref="schemaValidation" />
</message-filter>
<splitter expression="#[xpath('/rewardns:RewardOfferDetail/rewardns:Offer')]" doc:name="Split Message" />
<set-variable variableName="action" value="#[xpath('//rewardns:OperationCode')]" doc:name="Save Action Code"/>
<logger message="Action is: '#[flowVars.action]'" level="WARN" doc:name="Log Action Code"/>
Output:
13:53:39,653 DEBUG [org.mule.transport.jms.MultiConsumerJmsMessageReceiver] (TIBCO EMS Session Dispatcher (741)) Message received it is of type: TibjmsTextMessage
13:53:39,653 DEBUG [org.mule.transport.jms.MultiConsumerJmsMessageReceiver] (TIBCO EMS Session Dispatcher (741)) Message received on Queue[M.ESS.ITM.LOYALTY.STARS.ItemMaint] (com.tibco.tibjms.TibjmsQueue)
13:53:39,653 DEBUG [org.mule.transport.jms.MultiConsumerJmsMessageReceiver] (TIBCO EMS Session Dispatcher (741)) Message CorrelationId is:
13:53:39,653 DEBUG [org.mule.transport.jms.MultiConsumerJmsMessageReceiver] (TIBCO EMS Session Dispatcher (741)) Jms Message Id is: ID:EMS-SERVER.A305502CE7A4:995
13:53:39,653 DEBUG [org.mule.transport.jms.transformers.JMSMessageToObject] (TIBCO EMS Session Dispatcher (741)) Applying transformer JMSMessageToObject#218219976 (org.mule.transport.jms.transformers.JMSMessageToObject)
13:53:39,653 DEBUG [org.mule.transport.jms.transformers.JMSMessageToObject] (TIBCO EMS Session Dispatcher (741)) Object before transform:
org.mule.DefaultMuleMessage
{
id=998d2f50-13a0-11e5-b0f9-ac87a31af20c
payload=com.tibco.tibjms.TibjmsTextMessage
correlationId=
correlationGroup=-1
correlationSeq=-1
encoding=UTF-8
exceptionPayload=<not set>
Message properties:
INVOCATION scoped properties:
INBOUND scoped properties:
JMSCorrelationID=
JMSDeliveryMode=1
JMSDestination=Queue[M.ESS.ITM.LOYALTY.STARS.ItemMaint]
JMSExpiration=0
JMSMessageID=ID:EMS-SERVER.A305502CE7A4:995
JMSPriority=4
JMSRedelivered=false
JMSTimestamp=1426256459016
JMSType=
MULE_CORRELATION_ID=
MULE_MESSAGE_ID=ID:EMS-SERVER.A305502CE7A4:995
OUTBOUND scoped properties:
MULE_ENCODING=UTF-8
SESSION scoped properties:
}
13:53:39,654 DEBUG [org.mule.transport.jms.transformers.JMSMessageToObject] (TIBCO EMS Session Dispatcher (741)) Source object is TibjmsTextMessage
13:53:39,654 DEBUG [org.mule.transport.jms.transformers.JMSMessageToObject] (TIBCO EMS Session Dispatcher (741)) Message type received is: TibjmsTextMessage
13:53:39,654 DEBUG [org.mule.transport.jms.transformers.JMSMessageToObject] (TIBCO EMS Session Dispatcher (741)) Resulting object is String
13:53:39,654 DEBUG [org.mule.transport.jms.transformers.JMSMessageToObject] (TIBCO EMS Session Dispatcher (741)) Object after transform: <?xml version="1.0" encoding="UTF-8" ?>
<ns0:RewardOfferDetail xmlns:ns0="http://example.com/schemas/v1_0/RewardOffer">
<ns0:Offer>
<ns0:OperationCode>U</ns0:OperationCode>
</ns0:Offer>
<ns0:Offer>
<ns0:OperationCode>A</ns0:OperationCode>
</ns0:Offer>
</ns0:RewardOfferDetail>
13:53:39,654 DEBUG [org.mule.transport.jms.transformers.JMSMessageToObject] (TIBCO EMS Session Dispatcher (741)) The transformed object is of expected type. Type is: String
13:53:39,669 DEBUG [org.mule.expression.DefaultExpressionManager] ([loyalty-nebula].receiveMessageFlow.stage1.02) Result of expression: xpath-branch:/rewardns:RewardOfferDetail/rewardns:Offer is: [[ns0:Offer: null], [ns0:Offer: null]]
13:53:39,669 DEBUG [org.mule.processor.chain.DefaultMessageProcessorChain] ([loyalty-nebula].receiveMessageFlow.stage1.02) Invoking DefaultMessageProcessorChain '(inner iterating chain) of 'receiveMessageFlow' processor chain'
[
AddFlowVariableTransformer{this=589f1380, name='AddFlowVariableTransformer', ignoreBadInput=false, returnClass=SimpleDataType{type=java.lang.Object, mimeType='*/*'}, sourceTypes=[SimpleDataType{type=java.lang.Object, mimeType='*/*'}]},
org.mule.api.processor.LoggerMessageProcessor@be3c4ce,
org.mule.routing.requestreply.AsyncReplyToPropertyRequestReplyReplier
] with event MuleEvent: 0-998d2f53-13a0-11e5-b0f9-ac87a31af20c, stop processing=false, jms://M.ESS.ITM.LOYALTY.STARS.ItemMaint
13:53:39,669 DEBUG [org.mule.transformer.simple.AddFlowVariableTransformer] ([loyalty-nebula].receiveMessageFlow.stage1.02) Applying transformer AddFlowVariableTransformer (org.mule.transformer.simple.AddFlowVariableTransformer)
13:53:39,670 DEBUG [org.mule.transformer.simple.AddFlowVariableTransformer] ([loyalty-nebula].receiveMessageFlow.stage1.02) Object before transform:
org.mule.DefaultMuleMessage
{
id=998fa050-13a0-11e5-b0f9-ac87a31af20c
payload=org.apache.xerces.dom.ElementNSImpl
correlationId=<not set>
correlationGroup=2
correlationSeq=1
encoding=UTF-8
exceptionPayload=<not set>
Message properties:
INVOCATION scoped properties:
INBOUND scoped properties:
OUTBOUND scoped properties:
MULE_CORRELATION_GROUP_SIZE=2
MULE_CORRELATION_SEQUENCE=1
MULE_ENCODING=UTF-8
SESSION scoped properties:
}
13:53:39,670 DEBUG [org.mule.expression.DefaultExpressionManager] ([loyalty-nebula].receiveMessageFlow.stage1.02) Result of expression: xpath-branch://rewardns:OperationCode is: [[ns0:OperationCode: null], [ns0:OperationCode: null]]
13:53:39,670 DEBUG [org.mule.transformer.simple.AddFlowVariableTransformer] ([loyalty-nebula].receiveMessageFlow.stage1.02) Object after transform:
org.mule.DefaultMuleMessage
{
id=998fa050-13a0-11e5-b0f9-ac87a31af20c
payload=org.apache.xerces.dom.ElementNSImpl
correlationId=<not set>
correlationGroup=2
correlationSeq=1
encoding=UTF-8
exceptionPayload=<not set>
Message properties:
INVOCATION scoped properties:
action=[[ns0:OperationCode: null], [ns0:OperationCode: null]]
INBOUND scoped properties:
OUTBOUND scoped properties:
MULE_CORRELATION_GROUP_SIZE=2
MULE_CORRELATION_SEQUENCE=1
MULE_ENCODING=UTF-8
SESSION scoped properties:
}
13:53:39,671 DEBUG [org.mule.transformer.simple.AddFlowVariableTransformer] ([loyalty-nebula].receiveMessageFlow.stage1.02) The transformed object is of expected type. Type is: DefaultMuleMessage
13:53:39,672 WARN [org.mule.api.processor.LoggerMessageProcessor] ([loyalty-nebula].receiveMessageFlow.stage1.02) Action is: '[[ns0:OperationCode: null], [ns0:OperationCode: null]]'
This seems to work
From what @David was explaining it seems that xpath can still access elements throughout the entire document. A way to get around this was to use a
./
in the expression to anchor the function to use the current node as a starting point.So the final component looks like this:
The
splitter
produces messages withOffer
DOM elements as their payloads.If you use an xpath expression starting with
//
you are navigating back to the root element, which is still navigable from theOffer
element (because splitting doesn't detach the DOM nodes).So you need to base your xpath on the current
Offer
element with:Note that you could also use MEL instead of xpath to read the content of the
Offer
DOM element: