Author |
Message
|
sealpup |
Posted: Wed Nov 03, 2010 9:14 am Post subject: Cardinality and XML |
|
|
 Apprentice
Joined: 21 Sep 2010 Posts: 26
|
The solution to this has been proposed in other posts but it doesn't work for me.
Running Broker 7, MQ 7 on my local machine.
Input XML (I can have a variable number of <Opportunity> and a variable number of their children each time)
Code: |
<AWDSalesforceMessage>
<Opportunity>
<OpportunityId>270007</OpportunityId>
<OpportunityStage>morning</OpportunityStage>
<Surname>updated this morning</Surname>
<DateOfBirth>1924-10-01</DateOfBirth>
<CedingInsurer1>Kevin1</CedingInsurer1>
<TransferValue1>1110.00</TransferValue1>
<CedingInsurer2>Kevin2</CedingInsurer2>
</Opportunity>
<Opportunity>
<OpportunityId>270008</OpportunityId>
<OpportunityStage>morning</OpportunityStage>
<Surname>updated this morning</Surname>
<DateOfBirth>1924-10-01</DateOfBirth>
<CedingInsurer1>Kevin1</CedingInsurer1>
<TransferValue1>1110.00</TransferValue1>
</Opportunity>
</AWDSalesforceMessage> |
All I want to do is count how many <Opportunity> exist in my message. Ought to be easy, but I'm having dificulty excluding the children.
This code was suggested.
Code: |
SET Opps = CARDINALITY(Environment.Variables.InputXML.(XML.Element)*[]); |
But it still returns 7 rather than the 2 I seek.
Go on, put me out of my misery.
I should add that I populate the input XML into Environment.Variables.InputXML where InputXML corresponds to <AWDSalesforceMessage> |
|
Back to top |
|
 |
mgk |
Posted: Wed Nov 03, 2010 9:27 am Post subject: |
|
|
 Padawan
Joined: 31 Jul 2003 Posts: 1642
|
Hello,
Have you tried:
Code: |
SET Opps = CARDINALITY(Environment.Variables.AWDSalesforceMessage.Opportunity[]); |
?
Kind Regards, _________________ MGK
The postings I make on this site are my own and don't necessarily represent IBM's positions, strategies or opinions. |
|
Back to top |
|
 |
sealpup |
Posted: Wed Nov 03, 2010 9:44 am Post subject: |
|
|
 Apprentice
Joined: 21 Sep 2010 Posts: 26
|
Thanks for the suggestion.
Curiously that too returns '7'. Which just shows up my lack of understanding.
Here is the actual message tree during flow execution.
Code: |
WMQI_DebugMessage
WMQI_Message
WMQI_LocalEnvironment
WMQI_Environment
Variables
InputXML
Opportunity
OpportunityId CHARACTER 270007 CHARACTER
OpportunityStage CHARACTER this morning 10.02 CHARACTER
Surname CHARACTER updated this morning CHARACTER
DateOfBirth CHARACTER 1924-10-01 CHARACTER
CedingInsurer1 CHARACTER Kevin1 CHARACTER
TransferValue1 CHARACTER 1110.00 CHARACTER
CedingInsurer2 CHARACTER Kevin2 CHARACTER
Opportunity
OpportunityId CHARACTER 270008 CHARACTER
OpportunityStage CHARACTER this morning 10.02 CHARACTER
Surname CHARACTER updated this morning CHARACTER
DateOfBirth CHARACTER 1924-10-01 CHARACTER
CedingInsurer1 CHARACTER Kevin1 CHARACTER
TransferValue1 CHARACTER 1110.00 CHARACTER
WMQI_ExceptionList |
|
|
Back to top |
|
 |
Vitor |
Posted: Wed Nov 03, 2010 9:50 am Post subject: Re: Cardinality and XML |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
sealpup wrote: |
I should add that I populate the input XML into Environment.Variables.InputXML where InputXML corresponds to <AWDSalesforceMessage> |
Post the ESQL you're using to do this. I have a theory....  _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
fjb_saper |
Posted: Wed Nov 03, 2010 10:59 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Code: |
SET Opps = CARDINALITY(Environment.Variables.inputXML.*[]); |
Call me curious too. Why do you need the cardinality?
You could just as well use something like this:
Code: |
define cursor REFERENCE TO Environment.Variables.inputXML.Opportunity[1];
WHILE LASTMOVE(cursor) DO
[color=green]-- your code there[/color]
MOVE cursor NEXTSIBLING REPEAT TYPE NAME;
ENDWHILE;
|
 _________________ MQ & Broker admin |
|
Back to top |
|
 |
kimbert |
Posted: Wed Nov 03, 2010 12:59 pm Post subject: |
|
|
 Jedi Council
Joined: 29 Jul 2003 Posts: 5542 Location: Southampton
|
Quote: |
Curiously that too returns '7'. |
That is very unlikely indeed. I suspect that you are not using the exact ESQL that mgk posted. You are counting the children of the Opportunity tag. Did you perhaps write this?
Code: |
'...Opportunity.*[]' |
Regardless of whether that guess is correct, I agree with fjb_saper - best practice is to avoid the CARDINALITY function and use references. |
|
Back to top |
|
 |
sealpup |
Posted: Thu Nov 04, 2010 12:55 am Post subject: |
|
|
 Apprentice
Joined: 21 Sep 2010 Posts: 26
|
Thanks for your help.
I don't have to use CARDINALITY, but it should work....
Obviouisly I copied and pasted mgk's suggestion.
The reason I am surprised it returned anything at all, far less counting the children is that it is no longer part of the tree (as far as I understand it).
I take the input XML
Code: |
<AWDSalesforceMessage>
<Opportunity>
<OpportunityId>270007</OpportunityId>
<OpportunityStage>morning</OpportunityStage>
<Surname>updated this morning</Surname>
<DateOfBirth>1924-10-01</DateOfBirth>
<CedingInsurer1>Kevin1</CedingInsurer1>
<TransferValue1>1110.00</TransferValue1>
<CedingInsurer2>Kevin2</CedingInsurer2>
</Opportunity>
<Opportunity>
<OpportunityId>270008</OpportunityId>
<OpportunityStage>morning</OpportunityStage>
<Surname>updated this morning</Surname>
<DateOfBirth>1924-10-01</DateOfBirth>
<CedingInsurer1>Kevin1</CedingInsurer1>
<TransferValue1>1110.00</TransferValue1>
</Opportunity>
</AWDSalesforceMessage> |
Move it to Environment variables (in a subflow)
Code: |
SET Environment.Variables.InputXML = InputRoot.XMLNSC.AWDSalesforceMessage; |
and pass it on for later use
By the time I want to do the CARDINALITY, the tree is as I posted earlier, so I don't actually understand how mgk's suggestion should return anything. There is no Environment.Variables.AWDSalesforceMessage.* part of the tree at that point. The data is in Environment.Variables.InputXML.*. I debugged it to show myself. And yet mgk's suggestions still returns a value! (not hte oneI want though).
Of course some of you guys (with notable exceptions) won't believe me about the tree and assume I am blessed with some incompetence gene, merely becuase I am posting on here for assistance. But it's true. I wondering if there is a problem with CARDINALITY and the Environment.variables ?
Any suggestions will be received graciously. |
|
Back to top |
|
 |
kimbert |
Posted: Thu Nov 04, 2010 1:19 am Post subject: |
|
|
 Jedi Council
Joined: 29 Jul 2003 Posts: 5542 Location: Southampton
|
We're trying to help you here. Apologies for not assuming that you copied and pasted mgk's code. I must admit I'm struggling to understand why this is so hard - you should be able to diagnose this yourself without any trouble at all.
Please bear in mind the following points:
- You can take a user trace, and get a very detailed listing of what the message flow is doing. This is particularly useful in conjunction with Trace nodes, which write their output into the user trace.
- You are *copying* your data into the environment tree, not moving it. The copied data remains in InputRoot. |
|
Back to top |
|
 |
mgk |
Posted: Thu Nov 04, 2010 1:31 am Post subject: |
|
|
 Padawan
Joined: 31 Jul 2003 Posts: 1642
|
Well given this statement:
Quote: |
SET Environment.Variables.InputXML = InputRoot.XMLNSC.AWDSalesforceMessage; |
The cardinality should actually be:
Code: |
SET Opps = CARDINALITY(Environment.Variables.InputXML.Opportunity[]); |
If you still have problems, paste the full output from a trace node showing the Envrionment and InputRoot...
Regards, _________________ MGK
The postings I make on this site are my own and don't necessarily represent IBM's positions, strategies or opinions. |
|
Back to top |
|
 |
sealpup |
Posted: Thu Nov 04, 2010 2:03 am Post subject: |
|
|
 Apprentice
Joined: 21 Sep 2010 Posts: 26
|
Kimbert/mgk,
Thank you for your help. It is much appreciated.
In a flash of inspiration I have resolved this problem.
This code returns the wrong value (with children counted)
Code: |
SET Environment.Variables.InputXML = InputRoot.XMLNSC.AWDSalesforceMessage;
SET Opps = CARDINALITY(Environment.Variables.InputXML.Opportunity[]); |
If I simply place the data in the XMLNSC domain, bingo! It returns the correct value (not counting children).
This code returns the correct value
Code: |
SET Environment.Variables.XMLNSC.InputXML = InputRoot.XMLNSC.AWDSalesforceMessage;
SET Opps = CARDINALITY(Environment.Variables.XMLNSC.InputXML.Opportunity[]); |
This is the only change I have made.
Can you explain why this change works?
It's like it doesn't recognise the data structure properly unless it's in the XMLNSC domain.
Many thanks,
Kevin. |
|
Back to top |
|
 |
mgk |
Posted: Thu Nov 04, 2010 2:08 am Post subject: |
|
|
 Padawan
Joined: 31 Jul 2003 Posts: 1642
|
Hmm, the change you made should not have made any difference as you have not created a new parser, just a new element that happens to have the same name as a parser. However, what this has done is "push down" the level at which the data is copied in the tree, so if you have other code putting data into the same location then that would have been counted in the first case, but not in the second...
Can you paste the full output from a trace node showing the Envrionment and InputRoot and that should make things clearer...
Regards, _________________ MGK
The postings I make on this site are my own and don't necessarily represent IBM's positions, strategies or opinions. |
|
Back to top |
|
 |
sealpup |
Posted: Thu Nov 04, 2010 2:33 am Post subject: |
|
|
 Apprentice
Joined: 21 Sep 2010 Posts: 26
|
mgk,
It looks like it is the tree structure that is the problem. As you say I haven't added a new parser, so, this works too....
Code: |
SET Opps = CARDINALITY(Environment.Variables.anything.InputXML.Opportunity[]); |
I don't have time to do a trace just now. Seriously under the cosh.
Do you really want a trace?
If so I can do it next week.
Thanks,
Kevin. |
|
Back to top |
|
 |
Vitor |
Posted: Thu Nov 04, 2010 4:03 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
sealpup wrote: |
Move it to Environment variables (in a subflow)
Code: |
SET Environment.Variables.InputXML = InputRoot.XMLNSC.AWDSalesforceMessage; |
and pass it on for later use. |
So when it's in InputRoot it's a part of domain XMLNSC. What's it part of in the Environment?
Another point - what's one good reason XML.Element doesn't give the results you expect against a message in XMLNSC?
sealpup wrote: |
I debugged it to show myself. And yet mgk's suggestions still returns a value! (not hte oneI want though). |
I trust the debugger as far as I can throw it.
See above.
sealpup wrote: |
I wondering if there is a problem with CARDINALITY and the Environment.variables ? |
There's a problem with the way you're trying to use it certainly; my previous comments apply.
I'm also forced to ask why move the XML to the Environment tree and work on it, rather than save a move and act against InputRoot directly? _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
kimbert |
Posted: Thu Nov 04, 2010 4:13 am Post subject: |
|
|
 Jedi Council
Joined: 29 Jul 2003 Posts: 5542 Location: Southampton
|
Quote: |
I don't have time to do a trace just now. Seriously under the cosh. |
You have my sympathy, but aking a user trace cab be very easy. Write yourself some simple scripts that start, stop and format the user trace for you. I did it years ago and it has paid off many times over. |
|
Back to top |
|
 |
Vitor |
Posted: Thu Nov 04, 2010 4:29 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
sealpup wrote: |
In a flash of inspiration I have resolved this problem. |
This code returns the wrong value (with children counted)
sealpup wrote: |
If I simply place the data in the XMLNSC domain, bingo! It returns the correct value (not counting children). |
This code returns the correct value
sealpup wrote: |
It's like it doesn't recognise the data structure properly unless it's in the XMLNSC domain. |
So you're saying you've discovered that WMB doesn't recognise XML structure unless you associate it with an XML parser?
It's an important discovery.
Well done you.  _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
|