This topic provides information specific to dealing with messages that belong to the BLOB domain, and that are parsed by the BLOB parser.
You cannot manipulate the contents of a BLOB message, because it has no predefined structure. However, you can refer to its contents using its known position within the bit stream, and process the message with a minimum of knowledge about its contents.
The BLOB message body parser does not create a tree structure in the same way that other message body parsers do. It has a root element BLOB, that has a child element, also called BLOB, that contains the data.
You can refer to message content using substrings if you know the location of a particular piece of information within the BLOB data. For example, the following expression identifies the tenth byte of the message body:
InputBody.BLOB.BLOB[10]
The following expression references 10 bytes of the message data starting at offset 10:
SUBSTRING(InputBody.BLOB.BLOB from 10 for 10)
This example shows how to manipulate a variable length BLOB message. The example assumes that you have configured a message flow that receives a variable length BLOB message, parses some of the fields by invoking the MRM parser, and routes the output message to the correct output queue based on the information parsed.
The input message is in BLOB format and is assumed to contain embedded NULLs ('x00'), so it cannot be defined as null terminated.
This example shows the ESQL needed to:
By doing this, you can define the message model with an integer length field followed by the BLOB message.
This example also shows how to convert the BLOB message to CWF, process the message, and strip off the added length field.
In this example the input record has the following format:
This field is used as an integer to route the message to different queues depending on customer-defined criteria.
Define a new message BLOB_Example that includes the following elements and types:
This section describes the characteristics of the message flow. If you want to implement this example flow, you must complete the message flow definition (for example, by creating the three subflows to replace the output nodes used here to handle false, unknown, and failure cases) and provide any required support for its deployment and execution (for example, creating the inbound and any outbound queues on the queue manager for the broker to which you deploy the flow).
-- Declare local variables DECLARE I INTEGER 1; DECLARE J INTEGER CARDINALITY(InputRoot.*[]); DECLARE MSGLEN CHARACTER; DECLARE NUMBER INTEGER; DECLARE RESULT INTEGER; DECLARE REM INTEGER; -- Copy message headers WHILE I < J DO SET OutputRoot.*[I] = InputRoot.*[I]; SET I = I + 1; END WHILE; -- -- Set MSGLEN to non NULL to avoid errors when concatenating the first time -- SET MSGLEN = 'X'; -- -- Get the length of the BLOB and substract the length of VERSION_NUM and STORE_NUM (11+10) SET NUMBER = LENGTH("InputRoot"."BLOB"."BLOB")-21; -- -- Convert NUMBER to hexadecimal. The remainder of dividing by 16 is calculated recursively. -- WHILE NUMBER > 15 DO SET RESULT = NUMBER/16; SET REM = NUMBER - RESULT*16; SET MSGLEN = CASE WHEN REM < 10 THEN CAST(REM AS CHARACTER) || MSGLEN WHEN REM = 10 THEN 'A' || MSGLEN WHEN REM = 11 THEN 'B' || MSGLEN WHEN REM = 12 THEN 'C' || MSGLEN WHEN REM = 13 THEN 'D' || MSGLEN WHEN REM = 14 THEN 'E' || MSGLEN ELSE 'F' || MSGLEN END; SET NUMBER = RESULT; END WHILE; SET REM = NUMBER; SET MSGLEN = CASE WHEN REM < 10 THEN CAST(REM AS CHARACTER) || MSGLEN WHEN REM = 10 THEN 'A' || MSGLEN WHEN REM = 11 THEN 'B' || MSGLEN WHEN REM = 12 THEN 'C' || MSGLEN WHEN REM = 13 THEN 'D' || MSGLEN WHEN REM = 14 THEN 'E' || MSGLEN ELSE 'F' || MSGLEN END; -- -- Add leading '0's up to a length of 9 to be able to cast as BLOB. -- Remember it started with MSGLEN set to X (length 1) WHILE LENGTH(MSGLEN) < 9 DO SET MSGLEN = '0' || MSGLEN; END WHILE; -- -- Change to appropriate endian (PLATFORM DEPENDENT) -- If no endian swapping needed then remember to get rid of the last character as below -- SET MSGLEN = SUBSTRING(MSGLEN FROM 1 FOR 8); -- SET MSGLEN = SUBSTRING(MSGLEN FROM 7 FOR 2) || SUBSTRING(MSGLEN FROM 5 FOR 2) || SUBSTRING(MSGLEN FROM 3 FOR 2) || SUBSTRING(MSGLEN FROM 1 FOR 2); SET "OutputRoot"."BLOB"."BLOB" = CAST(MSGLEN AS BLOB) || "InputRoot"."BLOB"."BLOB";
CAST("Body"."e_STORE_NUM" AS INTEGER) < 151
This statement is based on the arbitrary assumption that an incoming message from a Store Number is less than 151 and is routed to a specific queue. You can code any other suitable test.
This subflow handles a message that has the expected format (the test performed in the Filter node returned true). The successful message is written to the output queue in its original form; the message is converted back to BLOB from MRM and the four bytes that were added (field B_LEN) are removed.
For this subflow:
-- Copy message headers DECLARE I INTEGER 1; DECLARE J INTEGER CARDINALITY(InputRoot.*[]); WHILE I < J DO SET OutputRoot.*[I] = InputRoot.*[I]; SET I = I + 1; END WHILE; -- -- Remove the 4 bytes length field added previously -- SET "OutputRoot"."BLOB"."BLOB" = SUBSTRING("InputRoot"."BLOB"."BLOB" FROM 5);
This Compute node removes the four bytes that were added at the beginning of the BLOB message to support its manipulation.
Note the use of a variable, J, initialized to the value of the cardinality of the existing headers in the message. This is more efficient than calculating the cardinality on each iteration of the loop, which happens if you code the following WHILE statement:
WHILE I < CARDINALITY(InputRoot.*[]) DO
Related concepts
Message flows
BLOB parser and domain
Promoted properties
ESQL
Message modeling
Related tasks
Designing a message flow
Defining message flow content
Configuring a node
Managing ESQL files
Defining promoted properties
Related reference
Compute node
Database node
Filter node
MQInput node
MQOutput node
ResetContentDescriptor node
ESQL
CARDINALITY function
CASE function
CAST function
DECLARE statement
SET statement
SUBSTRING function
WHILE statement
Notices |
Trademarks |
Downloads |
Library |
Support |
Feedback
![]() ![]() |
ac11640_ |