ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » Output structure treatment of NULL

Post new topic  Reply to topic Goto page 1, 2  Next
 Output structure treatment of NULL « View previous topic :: View next topic » 
Author Message
goffinf
PostPosted: Thu Jun 02, 2011 9:46 am    Post subject: Output structure treatment of NULL Reply with quote

Chevalier

Joined: 05 Nov 2005
Posts: 401

MB version 6.1.0.3

I perhaps should have known this but today I was surprised by .. :-

If I have code such as :-

Code:

SET OutputRoot.XMLNSC.response.text = InputRoot.XMLNSC.nonExistantField;


I expected no output to be created because the input evaluates to NULL (or maybe I'm wrong about that ?). But in fact what I get is :-

<response/>

That is, the output structure up to the final part is created anyway.

If instead I do this :-

Code:

DECLARE AmINULL CHAR InputRoot.XMLNSC.nonExistantField;
SET OutputRoot.XMLNSC.response.text = AmINULL;


no output structure is created at all.

Can someone explain the difference ?

This isn't just an acadmic question, I had (wrongly it seems) assumed that if I assign an output XMLNSC element in ESQL to an input element that doesn't exist, nothing would be produced (which is the effect I want).

Regards

Fraser.
Back to top
View user's profile Send private message
smdavies99
PostPosted: Thu Jun 02, 2011 10:27 am    Post subject: Reply with quote

Jedi Council

Joined: 10 Feb 2003
Posts: 6076
Location: Somewhere over the Rainbow this side of Never-never land.

Take a user trace and see what 'Wonderous Stories' are revealed.
_________________
WMQ User since 1999
MQSI/WBI/WMB/'Thingy' User since 2002
Linux user since 1995

Every time you reinvent the wheel the more square it gets (anon). If in doubt think and investigate before you ask silly questions.
Back to top
View user's profile Send private message
Vitor
PostPosted: Thu Jun 02, 2011 10:32 am    Post subject: Reply with quote

Grand High Poobah

Joined: 11 Nov 2005
Posts: 26093
Location: Texas, USA

Is there a message set associated with the output that defines the field as mandatory? I know you say you don't want it but just checking.
_________________
Honesty is the best policy.
Insanity is the best defence.
Back to top
View user's profile Send private message
goffinf
PostPosted: Thu Jun 02, 2011 10:56 am    Post subject: Reply with quote

Chevalier

Joined: 05 Nov 2005
Posts: 401

Actually it now appears that my initial testing was not correct. The case I sited where no output is produced (by assigning a variable first) *does* in fact produce the same (unwanted) output as the other example.

I have also tried this :-

Code:

SET OutputRoot.XMLNSC.response.text = COALESCE(InputRoot.XMLNSC.nonExistantField, NULL)


but it too still outputs <response/>

Victor: No there's no msgset involved here.

smdavies99: Sure I'll do that and post back here.

Fraser.
Back to top
View user's profile Send private message
mqjeff
PostPosted: Thu Jun 02, 2011 11:10 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

Try applying FP 8.

Try using VALUE clause.
Back to top
View user's profile Send private message
Vitor
PostPosted: Thu Jun 02, 2011 11:28 am    Post subject: Reply with quote

Grand High Poobah

Joined: 11 Nov 2005
Posts: 26093
Location: Texas, USA

mqjeff wrote:
Try applying FP 8.




Just tried it using WMB 6.1.0.9 and got the expected "Assigning NULL to <the target field name>, thus deleting it" in my user trace.

Interested to know what you see.
_________________
Honesty is the best policy.
Insanity is the best defence.
Back to top
View user's profile Send private message
smdavies99
PostPosted: Thu Jun 02, 2011 11:35 am    Post subject: Reply with quote

Jedi Council

Joined: 10 Feb 2003
Posts: 6076
Location: Somewhere over the Rainbow this side of Never-never land.

Vitor wrote:

Just tried it using WMB 6.1.0.9 and got the expected "Assigning NULL to <the target field name>, thus deleting it" in my user trace.

This has been true for sometime. I've often 'grepped' for the 'Assigning NULL' to find issued in code. IMHO, it is a neat trick.
_________________
WMQ User since 1999
MQSI/WBI/WMB/'Thingy' User since 2002
Linux user since 1995

Every time you reinvent the wheel the more square it gets (anon). If in doubt think and investigate before you ask silly questions.
Back to top
View user's profile Send private message
Vitor
PostPosted: Thu Jun 02, 2011 11:46 am    Post subject: Reply with quote

Grand High Poobah

Joined: 11 Nov 2005
Posts: 26093
Location: Texas, USA

smdavies99 wrote:
This has been true for sometime. I've often 'grepped' for the 'Assigning NULL' to find issued in code. IMHO, it is a neat trick.


It is the behaviour everyone including the OP seems to be expecting.

I certainly was expecting it.
_________________
Honesty is the best policy.
Insanity is the best defence.
Back to top
View user's profile Send private message
goffinf
PostPosted: Thu Jun 02, 2011 1:44 pm    Post subject: Reply with quote

Chevalier

Joined: 05 Nov 2005
Posts: 401

Vitor wrote:
smdavies99 wrote:
This has been true for sometime. I've often 'grepped' for the 'Assigning NULL' to find issued in code. IMHO, it is a neat trick.


It is the behaviour everyone including the OP seems to be expecting.

I certainly was expecting it.


Hmmm, I'm not so sure.

So taking the advice earlier of creating a User Trace, I do indeed see the ' Assigning NULL ...' as in :-

Code:

Assigning NULL to ''OutputRoot.XMLNSC.response.text'', thus deleting it.


But it seems to me that all that means is that it is deleting the 'text' part of the message tree but leaving the parts before it in tact, hence the output is <response/>.

What I was expecting was that NONE of the message tree would be constructed !
Back to top
View user's profile Send private message
rekarm01
PostPosted: Thu Jun 02, 2011 2:33 pm    Post subject: Re: Output structure treatment of NULL Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 1415

goffinf wrote:
But it seems to me that all that means is that it is deleting the 'text' part of the message tree but leaving the parts before it in tact, hence the output is <response/>.

What I was expecting was that NONE of the message tree would be constructed !

In order to navigate from the root to the target field, the SET statement will still try to create any missing fields along the way (or throw an exception if it can't), even when deleting the (possibly non-existent) target field.

So, in the given example, it will create a missing <response>, whether it creates <text> or not.

goffinf wrote:
If instead I do this, no output structure is created at all:
Code:
DECLARE AmINULL CHAR InputRoot.XMLNSC.nonExistentField;
SET OutputRoot.XMLNSC.response.text = AmINULL;

Now that would have been unexpected.

Perhaps adding an IF statement would work better:
Code:
IF InputRoot.XMLNSC.nonExistentField IS NOT NULL
THEN
    SET OutputRoot.XMLNSC.response.text = InputRoot.XMLNSC.nonExistentField;
END IF;
Back to top
View user's profile Send private message
goffinf
PostPosted: Thu Jun 02, 2011 2:50 pm    Post subject: Reply with quote

Chevalier

Joined: 05 Nov 2005
Posts: 401

Quote:
Perhaps adding an IF statement would work better:


Yes that would work and indeed that is a strategy that I have considered. However, ... I am mapping about 500 input elements and I don't really want the overhead of doing an IF test for each one just so i can supress (or rather not create) any partial output tree.

That said, thinking about the behaviour I see here and that others have confirmed, it *does* seem to be perfectly reasonable. That is, there's no way that MB could or probably should assume that just because the assignment to a 'leaf' node of the message tree turns out to be a NULL and causes that leaf not to be created, that it should assume I want all of the tree constructed up to the leaf to also be removed. Indeed if it did that it would be pretty disasterous for most of the code that most of us write I suppose.

Looks like I'm going to have to suck up the 500 IF tests, or use a different transformation method.

Fraser.
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Thu Jun 02, 2011 7:33 pm    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20756
Location: LI,NY

goffinf wrote:
Quote:
Perhaps adding an IF statement would work better:


Yes that would work and indeed that is a strategy that I have considered. However, ... I am mapping about 500 input elements and I don't really want the overhead of doing an IF test for each one just so i can supress (or rather not create) any partial output tree.

That said, thinking about the behaviour I see here and that others have confirmed, it *does* seem to be perfectly reasonable. That is, there's no way that MB could or probably should assume that just because the assignment to a 'leaf' node of the message tree turns out to be a NULL and causes that leaf not to be created, that it should assume I want all of the tree constructed up to the leaf to also be removed. Indeed if it did that it would be pretty disasterous for most of the code that most of us write I suppose.

Looks like I'm going to have to suck up the 500 IF tests, or use a different transformation method.

Fraser.
Don't do 500 IF tests. This will give you a prohibitive cost.
Build the tree and let the response be created. Go through your 500 fields... Then assign your reference to response. Move the reference to the last/first child. If the move is not successful remove the reference from the tree... done.

Have fun
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
goffinf
PostPosted: Fri Jun 03, 2011 2:33 am    Post subject: Reply with quote

Chevalier

Joined: 05 Nov 2005
Posts: 401

I had thought (I think) of something like this approach ... but figured it would probably still amount to the same thing (500 IF tests), that is, instead of 500 * IF fieldX IS NULL, I would still have 500 * IF LASTMOVE(Ref)

Did you mean build a temporary output tree in the Environment to recurse thru, ... then build up the actual OutputRoot as a result of testing the success (or not) of MOVE statements ?

or am I sadly misunderstanding something ?

Let me provide a more concrete example (simplified of course) :-

Lets say as a result of running the complete transformation ESQL I end up with this :-

Code:

<Person>
    <FirstName Val="Fred"/>
    <MiddleInitial />
    <Surname Val="Bloggs"/>
    <Age/>
    <Gender/>
    <Address>
        <Line1 Val="1 The Street"/>
        <Line2/>
        <Line3 Val="Sometown"/>
    </Address>
</Person>


I identify the problem as ... any element that does NOT have a Val attribute should not be included in the output so that means, these elements should be removed :-

<MiddleInitial />
<Age/>
<Gender/>
<Line2/>

The actual structure contains 500+ elements.

Using the approach you have [kindly] suggested how can I apply it to this structure.

Regards

Fraser.[/code]
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Fri Jun 03, 2011 8:53 pm    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20756
Location: LI,NY

goffinf wrote:

Let me provide a more concrete example (simplified of course) :-

Lets say as a result of running the complete transformation ESQL I end up with this :-

Code:

<Person>
    <FirstName Val="Fred"/>
    <MiddleInitial />
    <Surname Val="Bloggs"/>
    <Age/>
    <Gender/>
    <Address>
        <Line1 Val="1 The Street"/>
        <Line2/>
        <Line3 Val="Sometown"/>
    </Address>
</Person>


I identify the problem as ... any element that does NOT have a Val attribute should not be included in the output so that means, these elements should be removed :-

<MiddleInitial />
<Age/>
<Gender/>
<Line2/>

The actual structure contains 500+ elements.

Using the approach you have [kindly] suggested how can I apply it to this structure.

Regards

Fraser.


Again quite different from the previous proposal where the 500 tags where supposed to be children of the previous tag.
What you display here are final tags... so it looks like what you have in your code is
SET refperson.MiddleInitial VALUE = some null value ref;

Change that to

SET refperson.MiddleInitial = some null value ref;

This will create and delete the MiddleInitial tag in the same statement.

Now you only need to check the refperson at the end. If there are no children and the fieldValue(refperson) = null, you can then use
SET refperson = NULL;
and it will also delete the refperson tag. You then will need to move the reference as it no longer points to an existing location.

Have fun
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
goffinf
PostPosted: Sat Jun 04, 2011 5:45 am    Post subject: Reply with quote

Chevalier

Joined: 05 Nov 2005
Posts: 401

Hmm, I'm still confusing you with my example, my fault sorry.

This is the structure that I want to end up with AFTER the transformation (but WITHOUT the empty elements) :-

Code:

<Person>
    <FirstName Val="Fred"/>
    <MiddleInitial />
    <Surname Val="Bloggs"/>
    <Age/>
    <Gender/>
    <Address>
        <Line1 Val="1 The Street"/>
        <Line2/>
        <Line3 Val="Sometown"/>
    </Address>
</Person>


However, the source for this is NOT in the same structure, it looks more like this (note: not all of the elements expected in the output are present) :-

Code:

<Person>
    <FirstName>Fred</FirstName>
    <Surname>Bloggs</Surname>
    <Address>
        <Line1>1 The Street</Line1>
        <Line3>Sometown</Line3>
    </Address>
</Person>


So ... when I use code like this (choosing an example where the element I'm expecting to map is not actually present) :-

Code:

SET OutputRoot.XMLNSC.Person.MiddleInitial.(XMLNSC.Attribute)Val = InputRoot.XMLNSC.Person.MiddleInitial;


I end up with ...

Code:

<Person>
    ...
    <MiddleInitial />


Whilst what I want is for the MiddleInitial element to not appear at all in the output.

Thanks for you patience.

Fraser.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic  Reply to topic Goto page 1, 2  Next Page 1 of 2

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » Output structure treatment of NULL
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.