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 » Impossible to know if an xml field is empty

Post new topic  Reply to topic Goto page 1, 2  Next
 Impossible to know if an xml field is empty « View previous topic :: View next topic » 
Author Message
yazzam
PostPosted: Tue Feb 14, 2012 3:54 am    Post subject: Impossible to know if an xml field is empty Reply with quote

Newbie

Joined: 14 Feb 2012
Posts: 4

Hi,
Here is the situation:
I have an XML tree. I want to remove from it all the empty nodes dinamically.
Code:
<Flux>
  <a>
   <b><c/></b>
   <d/>
  </a>
</Flux>

Every thing works fine on the first itteration, and the node <c/> is deleted.
After the suppression of <c/> when the tree become like this:
Code:
<Flux>
  <a><b/><d/></a>
</Flux>

I want to delete the node <b/>
The problem is that I haven't find a way to know that this nod is empty

Here is an example code (without the dinamic part)
Code:

  SET OutputRoot = InputRoot;
  DECLARE cursor REFERENCE TO OutputRoot.XMLNSC.Flux;
  MOVE cursor to OutputRoot.XMLNSC.Flux.a.b.c;
  IF FIELDVALUE(cursor) = '' THEN
    SET Environment.Variables.cEmpty = 'true';
    DELETE FIELD cursor;
  END IF;
      
  MOVE cursor to OutputRoot.XMLNSC.Flux.a.b;
        
  SET Environment.Variables.bName = FIELDNAME(cursor);
  SET Environment.Variables.bVal = FIELDVALUE(cursor);
  SET Environment.Variables.b = cursor;
  SET Environment.Variables.Root = OutputRoot.XMLNSC;
  IF FIELDVALUE(cursor) = '' OR FIELDVALUE(cursor) = NULL OR cursor = NULL THEN
    SET Environment.Variables.bbbVide = 'true';
    DELETE FIELD cursor;
  END IF;


Adn her is the trace:
Code:

( ['MQROOT' : 0x116a1b410]
  (0x01000000:Name):Variables = (
    (0x03000000:NameValue):cEmpty = 'true' (CHARACTER)
    (0x03000000:NameValue):bName = 'b' (CHARACTER)
    (0x01000000:Name     ):b     =
    (0x01000000:Name     ):Root  = (
      (0x01000000:Name):XmlDeclaration = (
        (0x03000000:NameValue):Version  = '1.0' (CHARACTER)
        (0x03000000:NameValue):Encoding = 'ISO-8859-1' (CHARACTER)
      )
      (0x01000000:Name):Flux           = (
        (0x01000000:Name):a = (
         (0x01000000:Name):b =
          (0x01000000:Name):d =
        )
      )
    )
  )
)

the node </c> is detected as empty by the test
Code:
MOVE cursor to OutputRoot.XMLNSC.Flux.a.b.c;
  IF FIELDVALUE(cursor) = ''

but the same test on <b>
Code:
MOVE cursor to OutputRoot.XMLNSC.Flux.a.b;
IF FIELDVALUE(cursor) = '' OR FIELDVALUE(cursor) = NULL OR cursor = NULL

Doesn't detect that the node is empty.

Does any body see a solution ?
Thank you
Back to top
View user's profile Send private message
rekarm01
PostPosted: Tue Feb 14, 2012 4:02 am    Post subject: Re: Impossible to know if an xml field is empty Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 1415

yazzam wrote:
Code:
MOVE cursor to OutputRoot.XMLNSC.Flux.a.b;
IF FIELDVALUE(cursor) = '' OR FIELDVALUE(cursor) = NULL OR cursor = NULL

Use the LASTMOVE() function to determine whether the cursor reference is valid. Use the IS operator to test for NULL.
Back to top
View user's profile Send private message
yazzam
PostPosted: Tue Feb 14, 2012 5:17 am    Post subject: Reply with quote

Newbie

Joined: 14 Feb 2012
Posts: 4

Hi rekarm01,
Thank you for your answer.
I changed my code like this
Code:

MOVE cursor to OutputRoot.XMLNSC.Flux.a.b;
SET Environment.Variables.bLastMove = LASTMOVE(cursor);
  IF FIELDVALUE(cursor) IS NULL THEN
    SET Environment.Variables.bEmpty = 'true';
    DELETE FIELD cursor;
  END IF;

the trace is now:
Code:

(0x03000000:NameValue):bLastMove = TRUE (BOOLEAN)
(0x03000000:NameValue):bEmpty    = 'true' (CHARACTER)

So it's the result thant I need.
The problem is now that if I do the same test on a non empty node like <a> (<a> has children) the result is the same
Code:
Code:

MOVE cursor to OutputRoot.XMLNSC.Flux.a;
SET Environment.Variables.aLastMove = LASTMOVE(cursor);
IF FIELDVALUE(cursor) IS NULL THEN
  SET Environment.Variables.aEmpty = 'true';
END IF;

The trace is
Code:

(0x03000000:NameValue):aLastMove = TRUE (BOOLEAN)
(0x03000000:NameValue):aEmpty    = 'true' (CHARACTER)

It means that the FIELDVALUE of a node that have children is null as the FIELDVALUE of my node <b/> that became empty after the deleting of the node <c/>.
So I still can't detect that <b/> is empty.

The solution I think is to test that <b/> is null and has no children.
I'm going to test it
Back to top
View user's profile Send private message
kimbert
PostPosted: Tue Feb 14, 2012 5:33 am    Post subject: Reply with quote

Jedi Council

Joined: 29 Jul 2003
Posts: 5542
Location: Southampton

So you want to end up with a tree that contains no empty tags?
Currently you are walking the tree multiple times - that will be inefficient. A better approach would be something like this:
Code:
For each child of the root element
    zeroLength=true
    IF the current element has children
        For each child of the current element
            IF the child has a non-zero length,
                set zeroLength=false
    ELSE
        IF the current element has a non-zero length
            set zeroLength=false
    IF (zeroLength=true)
        delete this node


It's not quite as easy as that, because you need to be careful not to delete the node that you are positioned on. And you probably want a procedure that returns 0 or 1 depending on whether the node is zero-length, regardless of whether it has children. Then you can call that recursively.

But you get the idea - it's possible to do the job in a single pass over the tree.
Back to top
View user's profile Send private message
mqsiuser
PostPosted: Tue Feb 14, 2012 5:34 am    Post subject: Reply with quote

Yatiri

Joined: 15 Apr 2008
Posts: 637
Location: Germany

rekarm01 already gave you great tips!

Instead of checking for NULL with "field = NULL" you need to use "field IS NULL".

Also to check if a field exists move into it and check if the lastmove worked.

Or move into children and check if that worked, if you want to know whether a node has children.

To check the field value for NULL is strange: "FIELDVALUE(cursor) IS NULL"
_________________
Just use REFERENCEs


Last edited by mqsiuser on Tue Feb 14, 2012 5:35 am; edited 1 time in total
Back to top
View user's profile Send private message
mqjeff
PostPosted: Tue Feb 14, 2012 5:34 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

One generally does not expect that an xml element that has children will also have a value.

You can use LASTMOVE to check to see if you have succeeded in moving to the first child.
Back to top
View user's profile Send private message
yazzam
PostPosted: Tue Feb 14, 2012 5:41 am    Post subject: Reply with quote

Newbie

Joined: 14 Feb 2012
Posts: 4

Thank you all for your replies, I finnaly found a satisfiying test.
Code:

MOVE cursor to OutputRoot.XMLNSC.Flux.a;
SET Environment.Variables.aLastMove = LASTMOVE(cursor);

IF FIELDVALUE(cursor) IS NULL AND CARDINALITY(cursor.*[]) = 0 THEN
 SET Environment.Variables.aEmpty = 'true';
ELSE
  SET Environment.Variables.aEmpty = 'false';
END IF;


This test return false for nodes with value and nodes with children.
It returns true for empty nodes.

I jsut find verry strange that the test IF FIELDVALUE(cursor) = '' works for <c>
Code:

<Flux>
  <a>
   <b><c/></b>
   <d/>
  </a>
</Flux>

but don't work for <b> after deleting <c>
Code:

<Flux>
  <a>
   <b></b>
   <d/>
  </a>
</Flux>
Back to top
View user's profile Send private message
adubya
PostPosted: Tue Feb 14, 2012 5:43 am    Post subject: Reply with quote

Partisan

Joined: 25 Aug 2011
Posts: 377
Location: GU12, UK

FIELDVALUE examines element content not the presence of child elements.
Back to top
View user's profile Send private message Send e-mail
kimbert
PostPosted: Tue Feb 14, 2012 5:56 am    Post subject: Reply with quote

Jedi Council

Joined: 29 Jul 2003
Posts: 5542
Location: Southampton

Quote:
CARDINALITY(cursor.*[]) = 0
...could be slow if the cursor is positioned on something with a lot of child elements.
Better to try to move the cursor ( or a copy of it if you prefer ) to the first child, and remember whether the move succeeded. You will get the same answer a lot more efficiently.
Back to top
View user's profile Send private message
yazzam
PostPosted: Tue Feb 14, 2012 6:01 am    Post subject: Reply with quote

Newbie

Joined: 14 Feb 2012
Posts: 4

[/quote]
FIELDVALUE examines element content not the presence of child elements.
Quote:

Yes it's exacltly what I want to do the problem is that for two nodes with the same characteristic the result is different
Back to top
View user's profile Send private message
mqjeff
PostPosted: Tue Feb 14, 2012 6:15 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

yazzam wrote:
Yes it's exacltly what I want to do the problem is that for two nodes with the same characteristic the result is different


You haven't explained how you have managed to delete your <c/> element, and shown that this has ensure that the <b> element actually has no value.

What I mean is that very strictly according to the XML standard, the following
Code:
<b></b>
has no value, but
Code:
<b>
</b>
DOES have a value.

And, again, FIELDVALUE only tests the value of the element.
Back to top
View user's profile Send private message
kimbert
PostPosted: Tue Feb 14, 2012 6:33 am    Post subject: Reply with quote

Jedi Council

Joined: 29 Jul 2003
Posts: 5542
Location: Southampton

Quote:
FIELDVALUE examines element content

True.
Quote:
not the presence of child elements
Not quite true. If there are child elements of type 'Value' ( i.e. nodes with a value and no name ) then the text values of all such nodes will be concatenated together and returned as the value of the parent. You can get this situation when the content of an element is a CDATA section followed by some white space.

But that doesn't change your point very much. yazzam needs two separate algorithms:
a) determine whether the current element has a text value. FIELDVALUE does this.
b) determine whether the current element has any Name or NameValue child elements, so that he knows whether to recursively walk into the element. MOVE FIRSTCHILD does this, but remember that the child nodes might all be Value nodes, as described above, in which case the element has no *real* children.

Note that it is possible for an XML element to have both children AND a value. The value is then called 'mixed content'. By default the XMLNSC parser throws away mixed content so this will probably not be a problem for you.

Feel free to post your code when you're done. We can check it over for you, and then it will be available to other readers of this thread.
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Tue Feb 14, 2012 8:01 am    Post subject: Reply with quote

Grand High Poobah

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

And don't forget the particular case where a child does exist:

<a xsi:nil="true"/>


_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
kimbert
PostPosted: Tue Feb 14, 2012 1:09 pm    Post subject: Reply with quote

Jedi Council

Joined: 29 Jul 2003
Posts: 5542
Location: Southampton

fjb_saper is correct. It's not just xsi:nil either. What about namespace declarations? Is a tag 'empty' if it only contains namespace declarations? ( I think 'yes' ).

This highlights something that I was going to mention earlier; the requirement is difficult to implement whether you're using ESQL, XSLT or any other transformation language. It's easier to get it wrong than to get it right. So I would be interested to know why the receiving application needs these empty elements to be removed.
Back to top
View user's profile Send private message
mqsiuser
PostPosted: Tue Feb 14, 2012 8:07 pm    Post subject: Reply with quote

Yatiri

Joined: 15 Apr 2008
Posts: 637
Location: Germany

kimbert wrote:
It's not just xsi:nil either. What about namespace declarations? Is a tag 'empty' if it only contains namespace declarations? ( I think 'yes' ).

@fjb_saper: You are certainly aware of this, but I just like to state that you are talking about xml schema (xsd) definitions now and not (payload) xml. Though this could be, it likely is not the case for xml messages passing through.

@kimbert: Also note that the xml of the OP contains no namespaces (ok, if it would you'd have to consider this, ofc - but everything you don't use relieves you in that case). @OP: If you only have (your payload) XML, then there are only 2 types of children: elements & attributes. Well there is also content and probably it is mixed with elements ... but not in broker, because the parser takes care, afaiu, etc... ... but most notably: You are not having this in your xml (and nothing like that defined in your xsd ... that you probably have and ofc. validates). The OP's XML is elements only! A good decision for simplicities sake! ELSE there needs to be a decision what empty means: Contains no elements, but attributes are ok (choice 1), both not (choice 2) or both not but ignore some (e.g. xsd metadata attributes, e.g. namespace-prefixes) (choice 3). All of which the OP has gone rid off by using elements only!

kimbert wrote:
This highlights something that I was going to mention earlier; the requirement is difficult to implement whether you're using ESQL, XSLT or any other transformation language. It's easier to get it wrong than to get it right. So I would be interested to know why the receiving application needs these empty elements to be removed.


Question whether you need your requirement, but there certainly are (legacy) systems that stumble over stuff like that. @OP: your message is simple (no xml-attributes, no namespaces, no schema linked in, no metadata, no other weired stuff!), so that should be easy/doable in custom code (just to re-motivate you with your original idea)!

Be aware you are just programming some custom transformation code which relies on a certain (simple) in-xml-structure to realize custom requirements on the out-xml. Probably there can be some mini-utility functions ( e.g. hasChild(...), fieldExists(...) ), but probably no single function (that you'd possibly reuse later).

Probably the question is whether there always needs to be a custom (code) solution (ok and how well you get that to work&maintain) or if there can be a more generic function, which probably is not worth the hussel.

And: With ESQL (and Java) you have a real programming language. XSLT is much different and when you use it you are happy the first 80%, but then find out 15% is difficult/hard to do and (when your project deadline comes) that you can't do the last 5% at all. Not to mention performance degradation. I cannot understand why you just put ESQL and other technology, esp. XSLT on the same level.
_________________
Just use REFERENCEs
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 » Impossible to know if an xml field is empty
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.