Working with MRM messages and bit streams
When you use the ASBITSTREAM function or the CREATE FIELD statement with a PARSE clause you must consider various restrictions.
About this task
The ASBITSTREAM function
If you code the ASBITSTREAM function with the parser mode option set to RootBitStream, to parse a message tree to a bit stream, the result is an MRM document in the format specified by the message format that is built from the children of the target element in the normal way.
The target element must be a predefined message defined within the message set, or can be a self-defined message if you are using an XML physical format. This algorithm is identical to that used to generate the normal output bit stream. A well-formed bit stream obtained in this way can be used to re-create the original tree by using a CREATE statement with a PARSE clause.
If you code the ASBITSTREAM function with the parser mode option set to FolderBitStream, to parse a message tree to a bit stream, the generated bit stream is an MRM element built from the target element and its children. Unlike RootBitStream mode the target element does not have to represent a message; it can represent a predefined element within a message or self-defined element within a message.
So that the MRM parser can correctly parse the message, the path from the message to the target element within the message must be specified in the Message Type. The format of the path is the same as that used by message paths except that the message type prefix is not used.
Message
elem1
elem11
elem12
To serialize the subtree representing element elem12
and
its children, specify the message path 'message/elem1/elem12'
in
the Message Type.
If an element in the path
is qualified by a namespace, specify the namespace URI between {}
characters in the message path. For example if element elem1
is
qualified by namespace 'http://www.ibm.com/temp'
,
specify the message path as 'message/{http://www.ibm.com/temp}elem1/elem12'
This mode can be used to obtain a bit stream description of arbitrary sub-trees owned by an MRM parser. When in this mode, with a physical format of XML, the XML bit stream generated is not enclosed by the 'Root Tag Name' specified for the Message in the Message Set. No XML declaration is created, even if not suppressed in the message set properties.
Bit streams obtained in this way can be used to re-create the original tree by using a CREATE statement with a PARSE clause (by using a mode of FolderBitStream).
The CREATE statement with a PARSE clause
If you code a CREATE statement with a PARSE clause, with the parser mode option set to RootBitStream, to parse a bit stream to a message tree, the expected bit stream is a normal MRM document. A field in the tree is created for each field in the document. This algorithm is identical to that used when parsing a bit stream from an input node
If you code a CREATE statement with a PARSE clause, with the parser mode option set to FolderBitStream, to parse a bit stream to a message tree, the expected bit stream is a document in the format specified by the Message Format, which is either specified directly or inherited. Unlike RootBitStream mode the root of the document does not have to represent an MRM message; it can represent a predefined element within a message or self-defined element within a message.
So that the MRM parser can correctly parse the message the path from the message to the target element within the message must be specified in the Message Type. The format of the message path is the same as that used for the ASBITSTREAM function described above.
Example of using the ASBITSTREAM function and CREATE statement with a PARSE clause in FolderBitStream mode
The following ESQL uses the message definition described above. The ESQL serializes part of the input tree by using the ASBITSTREAM function, then uses the CREATE statement with a PARSE clause to re-create the subtree in the output tree. The Input message and corresponding Output message are shown below the ESQL.
CREATE COMPUTE MODULE DocSampleFlow_Compute
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
CALL CopyMessageHeaders();
-- Set the options to be used by ASBITSTREAM and CREATE ... PARSE
-- to be FolderBitStream and enable validation
DECLARE parseOptions INTEGER BITOR(FolderBitStream, ValidateContent,
ValidateValue, ValidateLocalError);
-- Serialise the elem12 element and its children from the input bitstream
-- into a variable
DECLARE subBitStream BLOB
ASBITSTREAM(InputRoot.MRM.elem1.elem12
OPTIONS parseOptions
SET 'DocSample'
TYPE 'message/elem1/elem12'
FORMAT 'XML1');
-- Set the value of the first element in the output tree
SET OutputRoot.MRM.elem1.elem11 = 'val11';
-- Parse the serialized sub-tree into the output tree
IF subBitStream IS NOT NULL THEN
CREATE LASTCHILD OF OutputRoot.MRM.elem1
PARSE ( subBitStream
OPTIONS parseOptions
SET 'DocSample'
TYPE 'message/elem1/elem12'
FORMAT 'XML1');
END IF;
-- Convert the children of elem12 in the output tree to uppercase
SET OutputRoot.MRM.elem1.elem12.elem121 =
UCASE(OutputRoot.MRM.elem1.elem12.elem121);
SET OutputRoot.MRM.elem1.elem12.elem122 =
UCASE(OutputRoot.MRM.elem1.elem12.elem122);
-- Set the value of the last element in the output tree
SET OutputRoot.MRM.elem1.elem13 = 'val13';
RETURN TRUE;
END;
CREATE PROCEDURE CopyMessageHeaders() BEGIN
DECLARE I INTEGER 1;
DECLARE J INTEGER CARDINALITY(InputRoot.*[]);
WHILE I < J DO
SET OutputRoot.*[I] = InputRoot.*[I];
SET I = I + 1;
END WHILE;
END;
END MODULE;
<message>
<elem1>
<elem11>value11</elem11>
<elem12>
<elem121>value121</elem121>
<elem122>value122</elem122>
</elem12>
<elem13>value13</elem13>
</elem1>
</message>
<message>
<elem1>
<elem11>val11</elem11>
<elem12>
<elem121>VALUE121</elem121>
<elem122>VALUE122</elem122>
</elem12>
<elem13>val13</elem13>
</elem1
</message