Author |
Message
|
jeasterl |
Posted: Mon Jul 07, 2003 10:34 am Post subject: Parsing data in a repeating structure |
|
|
 Acolyte
Joined: 24 Jun 2001 Posts: 65
|
I have to parse an incoming message that looks something like this...
aa100asbcefghij...............bb084abcdefj...............cc030abcdefg..........
All messages will begin with an 'aa', and there may be several instances of the 'aa' within a message. The numbers following the 'aa' indicate how long the segment is For example, this message has an 'aa' segment that is 100 bytes long. In this message flow, I am only concerned with data in the 'aa' segment and the 'cc' segment. By the way, there can be several instances of 'cc' as well.
What I am interested in knowing is how I would construct my EQSL to find find the first occurance of 'aa', pull the data from that segment, then move to the next segment. If that segment IS NOT a 'cc', then continue to look for the 'cc'. If it is a 'cc', then pull the data from that segment. I also need to ensure that I have gathered all the data from all instances of 'aa' and 'cc'.
Any suggestions are welcome! |
|
Back to top |
|
 |
inder |
Posted: Mon Jul 07, 2003 11:10 am Post subject: |
|
|
Apprentice
Joined: 24 Mar 2003 Posts: 49 Location: USA
|
Can you further explain what u need to do.
if you have message
aa0512345sdfkfcc09012345678se234555aa0312445dfdaa049876s2cc012xx1......
Does you need to take the data as
aa[1]-12345 cc[1]-012345678
aa[2]-124
aa[3]-9876 cc[3]-2
Or do you need to extract it in a different manner??
As my knowledge goes there is no direct function to do that. You have to use a combination of postion, substring and overlay functions to do this. Let me know so that I can post some example code
Regards
Inder |
|
Back to top |
|
 |
jeasterl |
Posted: Mon Jul 07, 2003 11:15 am Post subject: |
|
|
 Acolyte
Joined: 24 Jun 2001 Posts: 65
|
Your example is exactly what I am trying to do. Please post your sample code. I appriciate it.... |
|
Back to top |
|
 |
Craig B |
Posted: Mon Jul 07, 2003 11:31 am Post subject: |
|
|
Partisan
Joined: 18 Jun 2003 Posts: 316 Location: UK
|
Are you running WMQI V2.1 or above? If so, instead of using ESQL functions to manually parse this data, have you considered creating MRM message definitions to parse this data into a message tree? From your description it would seem that the TDS (Tagged Delimited Format) physical formats' "Tagged Encoded Length" data element separation would give you what you require. This identifies elements by a tag such as aa, bb, cc etc (as defined by the user) and then the user can define how many characters are read after the tag to give the length of the data. Once this length is extracted for a tag, then that amount of fixed data is read for that element.
If it is possible for you to use the MRM-TDS layer in you scenario, then this will be far better performing than ESQL processing to do a similar task. _________________ Regards
Craig |
|
Back to top |
|
 |
inder |
Posted: Mon Jul 07, 2003 11:41 am Post subject: |
|
|
Apprentice
Joined: 24 Mar 2003 Posts: 49 Location: USA
|
Check to see if the following code suffices your requirment
regards
Inder
Declare charData CHARACTER;
Declare blobData BLOB;
DECLARE AAPOS INT;
DECLARE CCPOS INT;
DECLARE CNT INT;
DECLARE AALEN INT;
DECLARE CCLEN INT;
Set blobData = BITSTREAM(InputBody);
Set charData = CAST(blobData AS CHARACTER CCSID InputRoot.MQMD.CodedCharSetId);
SET AAPOS = position('aa' in charData );
SET CNT = 1;
WHILE(AAPOS >0) DO
SET AALEN = CAST((SUBSTRING(charData FROM AAPOS+2 FOR 3)) AS INTEGER);
SET Environment.Variables.AA[CNT] = SUBSTRING(charData FROM AAPOS+5 FOR AALEN);
SET charData = overlay(charData placing '' from AAPOS-1 for AALEN+5);
SET AAPOS = position('aa' in charData );
SET CCPOS = position('cc' in charData );
IF((CCPOS >0) AND (AAPOS > CCPOS))
THEN
SET CCLEN = CAST((SUBSTRING(charData FROM CCPOS+2 FOR 3)) AS INTEGER);
SET Environment.Variables.CC[CNT] = SUBSTRING(charData FROM CCPOS+5 FOR CCLEN);
SET charData = overlay(charData placing '' from CCPOS-1 for CCLEN+5);
END IF;
SET CNT = CNT +1;
END WHILE; |
|
Back to top |
|
 |
jefflowrey |
Posted: Mon Jul 07, 2003 2:20 pm Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
I agree with Craig B that the original poster would be a lot better off trying to model this in MRM-TDS than parsing it with ESQL manually.
Among other things, it will allow them to more directly and easily translate this into another format - by allowing the parsers to do all of the physical representation work for you. |
|
Back to top |
|
 |
jeasterl |
Posted: Tue Jul 08, 2003 10:59 am Post subject: |
|
|
 Acolyte
Joined: 24 Jun 2001 Posts: 65
|
The code seems to work. I have to figure out how to get the data out of the Environment Variables.
One thing that I was curious about is why you deciced to do this:
Set charData = CAST(blobData AS CHARACTER CCSID InputRoot.MQMD.CodedCharSetId);
instead of this
Set charData = CAST(blobData AS CHARACTER);
When I tried the first ESQL, it was not able to find the data that I was looking for. The latter was able to find the code that I was looking for.
As for the reason that I am not using TDS, the characters that I am looking for, i.e. 'aa' and 'cc' are binary. The remaining data is character data that needs to be parsed. I was not sure if TDS was the best method. Casting the entire stirng as character and parsing the data based upon position in the string seemed better.
Thanks for the code, though. I believe that you have saved me a great deal of pain! |
|
Back to top |
|
 |
inder |
Posted: Tue Jul 08, 2003 11:18 am Post subject: |
|
|
Apprentice
Joined: 24 Mar 2003 Posts: 49 Location: USA
|
Quote: |
Casting Blob to character:
The result is a string conforming to the definition of a binary string
literal whose interpreted value is the same as the source value. The
result string will have the form X'hhhh' (where h is any hexadecimal
digit character).
If either a CCSID or ENCODING clause is specified, the given byte
array is assumed to be characters in the specified CCSID and encoding
and is code page converted into the character return value.
If only a CCSID is specified, bigendian encoding is assumed.
If only an encoding is specified, a CCSID of 1208 is assumed.
This function might report conversion errors if the given code page or
encoding are unknown, the data supplied is not an integral number of
characters of the given code page or the given data contains characters
that are not valid in the given code page. |
You can find the above information on page 116 of ESQL reference. Chapter 7. Transforming data from one data type to another
(CAST)
What do you mean by trying to find out a way of reading the environmental variables? |
|
Back to top |
|
 |
jeasterl |
Posted: Tue Jul 08, 2003 2:06 pm Post subject: |
|
|
 Acolyte
Joined: 24 Jun 2001 Posts: 65
|
I forgot to mention that the 'aa', 'cc', and segment lengths are coming in binary data with the remaining data coming in as character. I initially assumed that I would be able to cast the entire string as character, then parse the data. This will not be an issue for the binary data, but the character data is be converted to hex. Is there a way to convert only the binary data on input and not the character data? |
|
Back to top |
|
 |
|