当您使用 ASBITSTREAM 函数或带有 PARSE 子句的 CREATE FIELD 语句时,请注意以下几点。
ASBITSTREAM 函数
如果您在解析器方式选项设置为 RootBitStream 的情况下编写 ASBITSTREAM 函数的代码,将消息树解析为位流,则在通常情况下,结果为一个 MRM 文档,它的格式由从目标元素的子代构建的消息格式指定。
目标元素必须是在消息集内定义的预定义消息,或者如果使用 XML 物理格式,它可以是自定义的消息。此算法与用于生成常规输出位流的算法相同。以这种方法获得的格式完好的位流可以用来使用带有 PARSE 子句的 CREATE 语句重新创建原始树。
如果您在解析器方式选项设置为 FolderBitStream 的情况下编写 ASBITSTREAM 函数的代码,将消息树解析为位流,则所生成的位流是从目标元素及其子代构建的 MRM 元素。与 RootBitStream 方式不同,目标元素不一定表示消息;它可以表示消息内的预定义元素或消息内的自定义元素。
为使 MRM 解析器可以正确解析消息,必须在消息类型中指定从消息到消息内目标元素的路径。除不使用消息类型前缀之外,该路径的格式与消息路径使用的格式相同。
Message elem1 elem11 elem12
要序列化表示元素 elem12 及其子代的子树,请在消息类型中指定消息路径 'message/elem1/elem12'。
如果此路径中的元素由名称空间限定,则在消息路径中的 {} 字符之间指定该名称空间 URI。例如,如果元素 elem1 由名称空间 'http://www.ibm.com/temp' 限定,则将消息路径指定为 'message/{http://www.ibm.com/temp}elem1/elem12'
使用此方式可以获取 MRM 解析器所拥有的任意子树的位流描述。在此方式下,所生成的 XML 位流具有 XML 物理格式,在它的两边不使用为消息集中的消息指定的“根标记名称”。不创建任何 XML 声明,即使在消息集属性中不限制。
以这种方法获得的位流可以用来使用带有 PARSE 子句的 CREATE 语句(使用 FolderBitStream 方式)重新创建原始树。
带有 PARSE 子句的 CREATE 语句
如果在将解析器方式选项设置为 RootBitStream 的情况下,对带有 PARSE 子句的 CREATE 语句进行编码,将位流解析为消息树,则所期望的位流是一个普通 MRM 文档。对于该文档中的每个字段都将在该树中创建一个字段。此算法与从输入节点解析位流时使用的算法相同。
如果在将解析器方式选项设置为 FolderBitStream 的情况下,对带有 PARSE 子句的 CREATE 语句进行编码,将位流解析为消息树,则所期望的位流文档的格式由消息流格式直接指定或从消息流格式继承。与 RootBitStream 方式不同,该文档的根不一定表示 MRM 消息;它可以表示消息内的预定义元素或消息内的自定义元素。
为使 MRM 解析器可以正确解析消息,必须在消息类型中指定从消息到消息内目标元素的路径。该消息路径的格式与以上所述 ASBITSTREAM 函数所使用的格式相同。
以下 ESQL 使用了上述消息定义。ESQL 使用 ASBITSTREAM 函数将部分输入树序列化,然后使用带有 PARSE 子句的 CREATE 语句在输出树中重新创建子树。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