Converting EBCDIC NL to ASCII CR LF

You might want to change newline (NL) characters in a text message to carriage return (CR) and line feed (LF) character pairs. This example shows one way in which you can convert these characters.

About this task

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'. The ASCII code page has no corresponding code point for the NL character.

In this example, a message flow is created that interprets the input message as a message in the BLOB domain. This message 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 shown in the following diagram.

The diagram shows a linear message flow, which consists of the following nodes: MQInput, with Out terminal connected to ResetContentDescriptor, with Out terminal connected to Compute, with Out terminal connected to ResetContentDescriptor1, with Out terminal connected to MQOutput. No other terminals are connected.

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

Procedure

  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 Text1).
    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 an 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 previous figure:
    1. Start with the MQInput node:
      • Set Message Domain = BLOB
      • Set Queue Name = <Your input message queue name>
    2. Add the ResetContentDescriptor node, connected to the Out terminal of the MQInput node:
      • Set Message Domain = MRM
      • Select Reset Message Domain
      • Set Message Set = <Your Message Set ID> (this field has a maximum of 13 characters)
      • Select Reset Message Set
      • Set Message Type = msg_nl
      • Select Reset Message Type
      • Set Message Format = Text1
      • Select Reset Message Format
    3. Add the Compute node, connected to the Out terminal of the ResetContentDescriptor node:
      • Enter a name for the ESQL Module for this node, or accept the default (<message flow name>_Compute).
      • Right-click the Compute node, and select Open ESQL. Add the following ESQL code 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;

        The use of a variable, J, initialized to the value of the cardinality of the existing headers in the message, 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 ResetContentDescriptor1 node, connected to the Out terminal of the Compute node:
      • Set Message Domain = BLOB
      • Select Reset Message Domain.
    5. Finally, add the MQOutput node, connected to the Out terminal of the ResetContentDescriptor1 node. Configure its properties to direct the output message to the required queue or queues.