Converting EBCDIC NL to ASCII CR LF

This topic describes an example task that changes new line (NL) characters in a text message to carriage return (CR) and line feed (LF) character pairs.

This conversion might be useful if messages from an EBCDIC platform (for example, using CCSID 1047) are sent to an ASCII platform (for example, using CCSID 437). Problems can arise because the EBCDIC NL character hex '15' is converted to the undefined ASCII character hex '7F'. There is no corresponding code point for the NL character in the ASCII code page.

In this example, a message flow is created that interprets the input message as a message in the BLOB domain. This is passed into a ResetContentDescriptor node to reset the data to a message in the MRM domain. The message is called msg_nl (a set of repeating string elements delimited by EBCDIC NL characters). A Compute node is then used to create an output based on another message in the MRM domain called msg_crlf (a set of repeating string elements delimited by CR LF pairs). The message domain is then changed back to BLOB in another ResetContentDescriptor node. This message flow is illustrated below.


Diagram showing a linear message flow, comprised of nodes: MQInput1 with Out terminal connected to ResetContentDescriptor1, with Out terminal connected to Compute1, with Out terminal connected to ResetContentDescriptor2, with Out terminal connected to MQOutput1. No other terminals connected.

The following instructions show how to create the messages and configure the message flow.

  1. Create the message models for the messages in the MRM domain:
    1. Create a message set project called myProj.
    2. Create a message set called myMessageSet with a TDS physical format (the default name is TDS1).
    3. Create an element string1 of type xsd:string.
    4. Create a complex type called t_msg_nl and specify the following complex type properties:
      • Composition = Ordered Set
      • Content Validation = Closed
      • Data Element Separation = All Elements Delimited
      • Delimiter = <U+0085> (hex '0085' is the UTF-16 representation of a NL character)
      • Repeat = Yes
      • Min Occurs = 1
      • Max Occurs = 50 (the text of the message is assumed to consist of no more than 50 lines)
    5. Add Element string1 and set the following property:
      • Repeating Element Delimiter = <U+0085>
    6. Create a Message msg_nl and set its associated complex type to t_msg_nl
    7. Create a complex type called t_msg_crlf and specify the following complex type properties:
      • Composition = Ordered Set
      • Content Validation = Closed
      • Data Element Separation = All Elements Delimited
      • Delimiter <CR><LF> (<CR> and <LF> are the mnemonics for the CR and LF characters)
      • Repeat = Yes
      • Min Occurs = 1
      • Max Occurs = 50
    8. Add Element string1 and set the following property:
      • Repeating Element Delimiter = <CR><LF>
    9. Create a Message msg_crlf and set complex type to t_msg_crlf.
  2. Configure the message flow shown in the figure above:
    1. Start with the MQInput1 node:
      • Set Message Domain = BLOB
      • Set Queue Name = <Your input message queue name>
    2. Add the ResetContentDescriptor1 node, connected to the out terminal of MQInput1:
      • Set Message Domain = MRM
      • Select Reset Message Domain
      • Set Message Set = <Your Message Set ID> (this has a maximum of 13 characters)
      • Select Reset Message Set
      • Set Message Type = msg_nl
      • Select Reset Message Type
      • Set Message Format = TDS1
      • Select Reset Message Format
    3. Add the Compute1 node, connected to the out terminal of ResetContentDescriptor1:
      • Enter a name for the ESQL Module for this node, or accept the default (<message flow name>_Compute1).
      • Right-click the Compute1 node and select Open ESQL. Code the following ESQL in the module:
        -- Declare local working variables
        DECLARE I INTEGER 1;
        DECLARE J INTEGER CARDINALITY(InputRoot.*[]);
        
        -- Loop to copy all message headers from input to output message
        WHILE I < J DO
         	SET OutputRoot.*[I] = InputRoot.*[I];
         	SET I=I+1;
        END WHILE; 
        
        -- Set new output message type which uses CRLF delimiter
        SET OutputRoot.Properties.MessageType = 't_msg_crlf';
        
        -- Loop to copy each instance of string1 child within message body
        SET I = 1;
        SET J = CARDINALITY("InputBody"."string1"[]);
        WHILE I <= J DO
          SET "OutputRoot"."MRM"."string1"[I] = "InputBody"."string1"[I];
          SET I=I+1;
        END WHILE;

        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
    4. Add the ResetContentDescriptor2 node, connected to the out terminal of the Compute1 node:
      • Set Message Domain = BLOB
      • Select Reset Message Domain.
    5. Finally, add the MQOutput1 node, connected to the out terminal of the ResetContentDescriptor2 node. Configure its properties to direct the output message to the required queue or queues.
Related concepts
Message flows overview
ESQL overview
Message modeling
Related tasks
Designing a message flow
Defining message flow content
Managing ESQL files
Related reference
National language support
Compute node
MQInput node
MQOutput node
ResetContentDescriptor node
ESQL reference
DECLARE statement
SET statement
WHILE statement
TDS Mnemonics