Author |
Message
|
vanessa |
Posted: Fri May 17, 2002 11:09 am Post subject: XML into Multi messages - MQSI 2.0.2 |
|
|
Novice
Joined: 24 Jan 2002 Posts: 22
|
I am getting an xml message into the input node which has to be parsed into multiple messages using compute node....
I have MQSI 2.0.2 .. Sun OS ......how to build the logic in ESQL ..
Is there anything whcih is equivalent to Propagate in 2.1 ???
pls let me know...
Thanx in adv....  |
|
Back to top |
|
 |
kirani |
Posted: Fri May 17, 2002 11:57 am Post subject: |
|
|
Jedi Knight
Joined: 05 Sep 2001 Posts: 3779 Location: Torrance, CA, USA
|
|
Back to top |
|
 |
CodeCraft |
Posted: Sat May 18, 2002 12:07 am Post subject: |
|
|
Disciple
Joined: 05 Sep 2001 Posts: 195
|
I've done this before too, but only to prove to myself it can be done. One thing that concerns me here is that I believe for each iteration you are increasing the size of the stack, that is:
Though you are using a looping to enter a compute node N times, I suspect the DataFlowEngine will treat it as if you had actually gone through N compute nodes because it needs to be able to reverse the process should a failure occur.
Kirani, do you have a take on this? It may also depend on the transaction mode for the flow.
Another interesting point is that you can do this like a reverse recursion, without using a loop counter in the destination list.
For each time around the loop, split the process between two compute nodes. In compute node A, remove the last message and send the remainder of the tree back around the loop.
In compute node B, take just the last message and output it.
You know you're done when the cardinality of whichever branch your processing (outputting) reduces from N to just 1. |
|
Back to top |
|
 |
vanessa |
Posted: Sun May 19, 2002 7:35 pm Post subject: XML into Multi messages - MQSI 2.0.2 - URGENT |
|
|
Novice
Joined: 24 Jan 2002 Posts: 22
|
hi all
thanx for ur replies but my little brain couldnot understood the solution suggested .... i am a newbie...to mqsi..
my incoming xml message looks like:
<account_info>
<SSN = 1212 name=xyz address=23232 amount=2000/>
<SSN = 999 name=AVC address=89898 amount=9990/>
...
...
...
</account_info>
in mqsi i should PARSE and send multiple messages which would look like:
for example,
1st message would be...
<account_info>
<SSN = 1212 name=xyz address=23232 amount=2000/>
</account_info>
2nd message would be
<account_info>
<SSN = 999 name=AVC address=89898 amount=9990/>
</account_info>
how do i do this ..?? please give me some clue..
thanx in adv |
|
Back to top |
|
 |
Yanghui |
Posted: Mon May 20, 2002 2:20 am Post subject: |
|
|
Disciple
Joined: 08 May 2002 Posts: 151 Location: Dublin, Ireland
|
Hi, there,
From my understanding, it's quite easy to achieve what you want in ESQL. It's a kind of repeating tranfer from one layer to another. Check the latest ESQL document about how to handle xml repeating.
Hope it helps.
-Yanghui |
|
Back to top |
|
 |
CodeCraft |
Posted: Mon May 20, 2002 3:09 am Post subject: |
|
|
Disciple
Joined: 05 Sep 2001 Posts: 195
|
It's not as simple as that. The question is based on 2.02 so there is not that I remember a propagate function to spin the messages off from within a loop in the compute node.
A compute node in the flow needs to be set up, so that:
- It's output terminal is connect to an MQOutput node or other downstream node.
- It's output terminal is connect also to a filter node.
- The filter node needs to be able to do a state check, that is, test if all messages have actually been processed.
- If all messages have been processed, the filter node does not need to pass anything on.
- If all messages have not been processed, the filter node needs to pass *BACK* to the node which is processing the XML input message.
- You need to handle state like this:
- Put the whole INPUT message in the destination list tree.
- Put a counter in the destination list tree.
- Each time through the compute node, increment the counter. (You should set it to 0 (or 1, as your logic dictates) in an EARLIER compute node in the flow).
- This means, that everytime you reenter the compute node (which is effectively wired to itself via the following filter node), that you have information which allows you to determine which line of the XML input needs to be output this time.
- The compute mode of the compute node needs to be changed to include the destination list, otherwise the contents of the destination list will be lost between iterations around the loop.
- Alternatively, you could handle state using a database, but this would be less dynamic/efficient.
Is this any more clear? |
|
Back to top |
|
 |
Cliff |
Posted: Mon May 20, 2002 8:02 am Post subject: |
|
|
Centurion
Joined: 27 Jun 2001 Posts: 145 Location: Wiltshire
|
Vanessa,
there is another way to do this without using the DestinationList.
Wire the output from your upstream processing to a Filter node. Its Properties will be something like CARDINALITY(Root.XML.account_info[]) = 0. Don't wire True. Wire False to a Flow Order node. Wire the Output1 to a Compute node with properties : 'Copy message headers' and Set OutputRoot.XML.account_info = InputRoot.XML.account_info[FIRST]. wire the output to your MQOutput node.
Wire the FlowOrder Output2 to a Compute node, with properties 'Copy entire message' and Set OutputRoot.XML.account_info[FIRST] = NULL. This will remove that branch from the XML tree. Wire the output from that compute node to the Filter node to complete the loop.
Bingo! Job done.
Good luck - Cliff |
|
Back to top |
|
 |
Ward |
Posted: Mon May 20, 2002 8:13 am Post subject: |
|
|
 Voyager
Joined: 27 Jun 2001 Posts: 98 Location: Europe
|
Hi,
To get rid of the stack size problem you should make use of the FlowOrder node within your loop. This implicates using the DestinationList to keep track of where you are. When initiating and increasing the counter you should only propagate the DestinationList and not the message (so no OutputRoot = InputRoot as this will add the message onto your stack). The actual creation and writing of the output message you do in the First part of your FlowOrder node. The Second should be linked to your increase counter compute node.
Note that this way everything you change in both the message and the destination in the First leg of your computation will be lost when you go to the second leg... but then you can't keep things and get rid of the stack at the same time can you...
Hope this is enough an explanation but if you get into trouble let me know...
Cheers,
Ward. _________________ IBM Certified Solution Designer -- WebSphere MQ V6.0
IBM Certified Solution Developer - WebSphere Message Broker V6.0
----------------------------
Visit Boat Dimensions |
|
Back to top |
|
 |
kirani |
Posted: Mon May 20, 2002 8:54 am Post subject: |
|
|
Jedi Knight
Joined: 05 Sep 2001 Posts: 3779 Location: Torrance, CA, USA
|
Here is my $0.02 ...
Here is an example message flow that will create multiple output messages for you,
Considering following input message,
<Data>
<Tag1>First</Tag1>
<Tag1>Second</Tag1>
<Tag1>Third</Tag1>
<Tag1>Fourth</Tag1>
</Data>
My message flow will look like this,
MQInput(out)->Compute1(out)->Filter1(true)->FlowOrder1(first)->Compute2(out)->MQOutput1
FlowOrder1(second)->Compute3(out)->Filter1
and here is the ESQL code in each node,
Compute1
--------
[Set compute mode to DestinationList only]
Set OutputDestinationList.Variables.TotalCount = CARDINALITY(InputBody.Data.Tag1);
Filter1
-------
DestinationList.Variables.TotalCount > 0
Compute2
--------
[Copy Message Headers Only, Compute mode is set to Message only]
DECLARE CNT INT;
SET CNT = InputDestinationList.Variables.TotalCount;
SET OutputRoot.XML.Data.Tag1 = InputBody.Data.Tag1[CNT];
MQOutput1
--------
Your output queue name
Compute3
--------
[Don't select anything (copy message headers or copy entire message). Set compute mode to DestinationList only]
SET OutputDestinationList.Variables.TotalCount = InputDestinationList.Variables.TotalCount - 1;
If you send above XML message as input to this message flow, it will generate following 4 output messages,
<Data><Tag1>First</Tag1></Data>
<Data><Tag1>Second</Tag1></Data>
<Data><Tag1>Third</Tag1></Data>
<Data><Tag1>Fourth</Tag1></Data>
Vanessa,
You may have problem with this if you are dealing with large number of repeatations. I am assuming your transaction mode is set to Yes for the message flow.
Codecraft,
Why do you think we should copy original XML message into DestinationList? You already have original copy of the input message in the memory and we can refer to it while processing. Am I missing something here?
Cliff,
1. Using CARDINALITY function in Filter node, which will be called N number of times is not a good idea.
2. By copying complete message in a compute node (which is connected to Output2 of Floworder node) you are increasing the number of trees in the memory.
Hope this helps. _________________ Kiran
IBM Cert. Solution Designer & System Administrator - WBIMB V5
IBM Cert. Solutions Expert - WMQI
IBM Cert. Specialist - WMQI, MQSeries
IBM Cert. Developer - MQSeries
|
|
Back to top |
|
 |
Cliff |
Posted: Tue May 21, 2002 1:30 am Post subject: |
|
|
Centurion
Joined: 27 Jun 2001 Posts: 145 Location: Wiltshire
|
Gents,
yes, you're right, yours is the better method. Still, we'll all soon be PROPAGATEing, I guess ....
Cheers - Cliff |
|
Back to top |
|
 |
vanessa |
Posted: Tue May 21, 2002 1:39 pm Post subject: |
|
|
Novice
Joined: 24 Jan 2002 Posts: 22
|
Thanks guys... it was working fine with Kirani's xml
but the xml data which I get would actually look like
<Data>
<Tag1 name ="one" ></Tag1>
<Tag1 name ="abc"></Tag1>
<Tag1 name ="xyz"></Tag1>
<Tag1 name ="hello"></Tag1>
</Data>
I followed the same procedure till all the steps mentioned by Kirani and
my code in the final compute node is ....
DECLARE CNT INT;
SET CNT = InputDestinationList.Variables.TotalCount;
SET OutputRoot.XML.Data.Tag1[CNT].(XML.Attribute)name = InputBody.Data.Tag1[CNT].name;
This is giving error ...
Any body has got clues ....
ThanX in adv... |
|
Back to top |
|
 |
kirani |
Posted: Tue May 21, 2002 6:19 pm Post subject: |
|
|
Jedi Knight
Joined: 05 Sep 2001 Posts: 3779 Location: Torrance, CA, USA
|
Vanessa,
You don't need [CNT] in your ESQL. Try changing your ESQL to...
DECLARE CNT INT;
SET CNT = InputDestinationList.Variables.TotalCount;
SET OutputRoot.XML.Data.Tag1 = InputBody.Data.Tag1[CNT]; _________________ Kiran
IBM Cert. Solution Designer & System Administrator - WBIMB V5
IBM Cert. Solutions Expert - WMQI
IBM Cert. Specialist - WMQI, MQSeries
IBM Cert. Developer - MQSeries
|
|
Back to top |
|
 |
CodeCraft |
Posted: Tue May 28, 2002 1:50 pm Post subject: |
|
|
Disciple
Joined: 05 Sep 2001 Posts: 195
|
kirani wrote: |
Codecraft,
Why do you think we should copy original XML message into DestinationList? You already have original copy of the input message in the memory and we can refer to it while processing. Am I missing something here?
|
Depends on precisely the solution you use, but, if the reduced output from the compute also becomes the new input to the same compute, then you are not referencing the original input message, but the output message? So, do you not need a copy of the complete message which first arrived at the compute node before you started looping? |
|
Back to top |
|
 |
|