When you use the ASBITSTREAM function or the CREATE FIELD statement with a PARSE clause note the following points.
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 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 recreate the original tree 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 recreate the original tree using a CREATE statement with a PARSE clause (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.
The following ESQL uses the message definition described above. The ESQL serializes part of the input tree using the ASBITSTREAM function, and then uses the CREATE statement with a PARSE clause to recreate 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 CAST(ASBITSTREAM(InputRoot.MRM.elem1.elem12 OPTIONS parseOptions SET 'DocSample' TYPE 'message/elem1/elem12' FORMAT 'XML1') AS BLOB); -- 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