CREATE statement
The CREATE statement creates a new message field.
Syntax
- 1 Do not use the DomainClause and ParseClause with the FIELD qualifier.
- 2 Use the RepeatClauses only with the PREVIOUSSIBLING and NEXTSIBLING qualifiers.
- 3 Each subclause within the ParseClause can occur once only.
- 4 If present, the TYPE, NAMESPACE, and NAME elements must appear in the order that is shown in the railroad diagram.
The new message field is positioned either at a given location (CREATE FIELD) or relative to a currently existing location (CREATE ... OF...). New fields can be created only when the target field reference points to a modifiable message; for example, Environment, InputLocalEnvironment, OutputLocalEnvironment, OutputRoot, or OutputExceptionList.
If you include a FIELD clause, the field that is specified by Target is navigated to (creating the fields, if necessary) and any values clause, or from clause, is processed. Including a FIELD clause does not necessarily create any fields; it ensures only that the given fields exist.
SET OutputRoot.XMLNS.Message.Structure[2].Field = ...
At least one instance of Structure must already exist in the message. That is, the only fields in the tree that are created are ones on a direct path from the root to the field identified by the field reference.
If you include a PREVIOUSSIBLING, NEXTSIBLING, FIRSTCHILD, or LASTCHILD clause, the field that is specified by Target is navigated to (creating the fields if necessary) in the same way as for the FIELD clause. A new field is then created and attached in the specified position (for example, as PREVIOUSSIBLING or FIRSTCHILD). A CREATE statement with one of these clauses always creates a new field, and places it in the specified position.
If you use two CREATE FIRSTCHILD OF target statements that specify the same target, the second statement creates a new field as the first child of the target, and displaces the previously created first child to the right in the message tree (so that it is no longer the first child). Similarly, CREATE LASTCHILD OF target navigates to the target field and adds a new field as its rightmost child, displacing the previous last child to the left.
CREATE PREVIOUSSIBLING OF Target creates a field to the immediate left of the field that is specified by Target (so the depth of the tree is not changed). Similarly, CREATE NEXTSIBLING OF Target creates a field to the immediate right of the field that is specified by Target. When you create PREVIOUSSIBLING or NEXTSIBLING, you can use the REPEAT keyword to copy the type and name of the new field from the current field.
AS clause:
If present, the AS clause moves the named reference variable to point at the newly created field. Use this clause if you want to involve the new field in some further processing.
DOMAIN clause:
If present, the DOMAIN clause associates the new field with a new parser of the specified type. This clause expects a root field name (for example, XMLNS or MQRFH2). If the DOMAIN clause is present, but the value that is supplied is a zero-length character string, a new parser of the same type as the parser that owns the field that is specified by target is created. An exception is thrown if the supplied domain name is not CHARACTER data type or its value is NULL. Do not specify the DOMAIN clause with the FIELD clause; it is not certain that a new field is created.
REPEAT clause:
- Copied from any existing field (using the FROM clause)
- Specified explicitly (using the VALUES clause)
- Defined by parsing a bit stream (using the PARSE clause)
VALUES clause:
For the VALUES clause, the type, name, and value (or any subset of these) can be specified by any expression that returns a suitable data type (INTEGER for type, CHARACTER for name, and any scalar type for value). An exception is thrown if the value supplied for a type or name is NULL.
NAMES clause:
NAMESPACE | NAME | Element named as follows |
---|---|---|
No | No | The element is nameless (the name flag is not automatically set). |
No | Yes | The element is given the name in the default namespace. |
Yes | No | The element is given the empty name in the given namespace. |
Yes | Yes | The element is given the given name in the given namespace. |
The IDENTITY operand takes a single path element in place of the TYPE and NAME clauses, where a path element contains (at most) a type, a namespace, a name, and an index. These elements specify the type, namespace, name, and index of the element to be created and follow all the rules described in the topic for field references (see ESQL field reference overview). For example:
IDENTITY (XMLNS.attribute)Space1:Name1[42]
See the following Examples section for information about how to use the IDENTITY operand.
FROM clause:
For the FROM clause, the new field's type, name, and value are taken from the field pointed to by SourceFieldReference. Any existing child fields of the target are detached (the field might already exist in the case of a FIELD clause), and the new field is given copies of the source field's children.
PARSE clause:
If a PARSE clause is present, a subtree is built under the newly-created field from the supplied bit stream. The algorithm for building the subtree varies from parser to parser and according to the options specified. All parsers support the mode RootBitStream, in which the tree creation algorithm is the same as that used by an input node.
Some parsers also support a second mode, FolderBitStream, which generates a sub tree from a bit stream created by the ASBITSTREAM function (see ASBITSTREAM function) that is using that mode.
When you use the PARSE clause, specify a scalar
value containing the bit stream that is to be parsed for BitStreamExpression.
If you use a message tree field reference you must ensure it contains
a scalar value that contains the bit stream. An existing message body
folder such as InputRoot.XMLNSC
does not contain
a bit stream and therefore cannot be used this to serialize the XMLNS
folder.
If you pass a value other than a scalar containing the bit stream
to the PARSE clause for BitStreamExpression, the
message flow produces a BIP2906
error message. Instead,
you must first call the ASBITSTREAM function to serialize the existing
message tree folder. The result of the ASBITSTREAM function can then
be passed as the BitStreamExpression to the PARSE
clause.
DECLARE inCCSID INT InputProperties.CodedCharSetId;
DECLARE inEncoding INT InputProperties.Encoding;
DECLARE inBitStream BLOB ASBITSTREAM(InputRoot.XMLNSC, inEncoding, inCCSID);
CREATE LASTCHILD OF OutputRoot DOMAIN('MRM')
PARSE(inBitStream, inEncoding, inCCSID, 'DP3UK14002001',
'TestCase', 'XML1', options);
When the PARSE statement is processed, any PARSE clause expressions are evaluated. An exception is thrown if any of the following expressions do not result in a non-null value of the appropriate type:
Clause | Type | Default value |
---|---|---|
OPTIONS | Integer | RootBitStream & ValidateNone |
ENCODING | Integer | 0 |
CCSID | Integer | 0 |
SET | Character | Zero length string |
TYPE | Character | Zero length string |
FORMAT | Character | Zero length string |
For details of the syntax of the TYPE clause, see Specifying namespaces in the Message property.
Although the OPTIONS clause accepts any expression that returns a value of type integer, it is only meaningful to generate option values from the list of supplied constants, using the BITOR function if more than one option is required.
Validate master options...
ValidateContentAndValue
ValidateValue -- Can be used with ValidateContent
ValidateContent -- Can be used with ValidateValue
ValidateNone
Validate failure action options...
ValidateException
ValidateExceptionList
ValidateLocalError
ValidateUserTrace
Validate timing options...
ValidateComplete
ValidateImmediate
ValidateDeferred
- For full details of the validation options, refer to Validation properties.
- The Validate timing options correspond to Parse Timing options and, in particular, ValidateDeferred corresponds to Parse Timing On Demand.
- Equivalent validation options are not available in the C plugin node API methods cniCreateElementAsLastChildFromBitstream() and cniElementAsBitstream().
- The Java plugin node API MBElement methods createElementAsLastChildFromBitstream() and toBitstream() provide validation options. However, the FolderBitStream and EmbeddedBitStream modes are not available. The only available mode is RootBitStream, which is the default value.
You can specify only one option from each group, with the exception of ValidateValue and ValidateContent, which you can use together to obtain the content and value validation. If you do not specify an option within a group, the option in bold is used.
MQENC_INTEGER_NORMAL
MQENC_INTEGER_REVERSED
MQENC_DECIMAL_NORMAL
MQENC_DECIMAL_REVERSED
MQENC_FLOAT_IEEE_NORMAL
MQENC_FLOAT_IEEE_REVERSED
MQENC_FLOAT_S390
The values used for the CCSID clause follow the normal numbering system. For example, 1200 = UCS-2, 1208 = UTF-8.
For absent clauses, the given default values are used. Use the CCSID and encoding default values because these take their values from the queue manager's encoding and CCSID settings.
Similarly, using the default values for each of the message set, type, and format options is useful, because many parsers do not require message set, type, or format information, and so any valid value is sufficient.
ENCODING -> CCSID -> SET -> TYPE -> FORMAT -> OPTIONS
The list can be truncated at any point and an entirely empty expression can be used in any clauses where you do not supply a value.
Examples of how to use the CREATE statement
- The following example creates the specified field:
CREATE FIELD OutputRoot.XMLNS.Data;
- The following example creates a field with no name, type, or value
as the first child of
ref1
:CREATE FIRSTCHILD OF ref1;
- The following example creates a field using the specified type,
name, and value:
CREATE NEXTSIBLING OF ref1 TYPE NameValue NAME 'Price' VALUE 92.3;
- The following example creates a field with a type and name, but
no value; the field is added before the sibling indicated by the dynamic
reference (
ref1
):CREATE PREVIOUSSIBLING OF ref1 TYPE Name NAME 'Quantity';
- The following example creates a field named Component, and moves
the reference variable targetCursor to point at it:
CREATE FIRSTCHILD OF targetCursor AS targetCursor NAME 'Component';
- The following example creates a new field as the right sibling
of the field pointed to by the reference variable targetCursor having
the same type and name as that field. The statement then moves targetCursor
to point at the new field:
CREATE NEXTSIBLING OF targetCursor AS targetCursor REPEAT;
- The following example shows how to use the PARSE
clause:
DECLARE bodyBlob BLOB ASBITSTREAM(InputRoot.XMLNS, InputProperties.Encoding, InputProperties.CodedCharSetId); DECLARE creationPtr REFERENCE TO OutputRoot; CREATE LASTCHILD OF creationPtr DOMAIN('XMLNS') PARSE(bodyBlob, InputProperties.Encoding, InputProperties.CodedCharSetId);
This example can be extended to show the serializing and parsing of a field or folder:
DECLARE bodyBlob BLOB ASBITSTREAM(InputRoot.XMLNS.TestCase.myFolder, InputProperties.Encoding, InputProperties.CodedCharSetId,",",",FolderBitStream); DECLARE creationPtr REFERENCE TO OutputRoot; CREATE LASTCHILD OF creationPtr DOMAIN('XMLNS') PARSE(bodyBlob, InputProperties.Encoding, InputProperties.CodedCharSetId,",",",FolderBitStream);
- The following example shows how to use the IDENTITY operand:
CREATE FIELD OutputRoot.XMLNS.TestCase.Root IDENTITY (XML.ParserRoot)Root; CREATE FIELD OutputRoot.XMLNS.TestCase.Root.Attribute IDENTITY (XML.Attribute)NSpace1:Attribute VALUE 'Attrib Value'; CREATE LASTCHILD OF OutputRoot.XMLNS.TestCase.Root IDENTITY (XML.Element)NSpace1:Element1[1] VALUE 'Element 1 Value'; CREATE LASTCHILD OF OutputRoot.XMLNS.TestCase.Root IDENTITY (XML.Element)NSpace1:Element1[2] VALUE 'Element 2 Value';
This produces the following output message:
<TestCase> <Root xmlns:NS1="NSpace1" NS1:Attribute="Attrib Value"> <NS1:Element1>Element 1 Value</NS1:Element1> <NS1:Element1>Element 2 Value</NS1:Element1> </Root> </TestCase>
- The following example shows how you can use the DOMAIN clause to avoid losing information unique
to the XMLNS parser when an unlike parser copy
occurs:
DECLARE bodyBlob BLOB ASBITSTREAM(InputRoot.XMLNS, InputProperties.Encoding, InputProperties.CodedCharSetId); CREATE FIELD Environment.Variables.myXMLTree; DECLARE creationPtr REFERENCE TO Environment.Variables.myXMLTree; CREATE FIRSTCHILD OF creationPtr DOMAIN('XMLNS') PARSE(bodyBlob, InputProperties.Encoding, InputProperties.CodedCharSetId);
- The following example assumes that InputRoot.BLOB.BLOB
contains an XML document, and shows how to pass a single parser option into the PARSE clause in a
CREATE statement:
CREATE LASTCHILD OF OutputRoot DOMAIN('XMLNSC') PARSE(InputRoot.BLOB.BLOB, InputRoot.Properties.Encoding, InputRoot.Properties.CodedCharSetId, '', '', '', XMLNSC.MixedContentRetainAll);
- The following is another example that assumes that
InputRoot.BLOB.BLOB contains an XML document, and shows how to pass multiple
parser and validation options into the PARSE clause in a CREATE statement. The particular options
require an XML Schema, which in this example resides in a shared library called
mySchemaLibrary:
CREATE LASTCHILD OF OutputRoot DOMAIN('XMLNSC') PARSE(InputRoot.BLOB.BLOB, InputRoot.Properties.Encoding, InputRoot.Properties.CodedCharSetId, '{mySchemaLibrary}', '', '', BITOR(XMLNSC.BuildTreeUsingSchemaTypes, ValidateContentAndValue));
An example of a CREATE statement
This example provides sample ESQL and an input message.
CREATE COMPUTE MODULE CreateStatement_Compute
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
CALL CopyMessageHeaders();
CREATE FIELD OutputRoot.XMLNS.TestCase.description TYPE NameValue VALUE 'This is my TestCase' ;
DECLARE cursor REFERENCE TO OutputRoot.XMLNS.TestCase;
CREATE FIRSTCHILD OF cursor Domain('XMLNS')
NAME 'Identifier' VALUE InputRoot.XMLNS.TestCase.Identifier;
CREATE LASTCHILD OF cursor Domain('XMLNS') NAME 'Sport' VALUE InputRoot.XMLNS.TestCase.Sport;
CREATE LASTCHILD OF cursor Domain('XMLNS') NAME 'Date' VALUE InputRoot.XMLNS.TestCase.Date;
CREATE LASTCHILD OF cursor Domain('XMLNS') NAME 'Type' VALUE InputRoot.XMLNS.TestCase.Type;
CREATE FIELD cursor.Division[1].Number TYPE NameValue VALUE 'Premiership';
CREATE FIELD cursor.Division[1].Result[1].Number TYPE NameValue VALUE '1' ;
CREATE FIELD cursor.Division[1].Result[1].Home TYPE Name;
CREATE LASTCHILD OF cursor.Division[1].Result[1].Home NAME 'Team' VALUE 'Liverpool' ;
CREATE LASTCHILD OF cursor.Division[1].Result[1].Home NAME 'Score' VALUE '4';
CREATE FIELD cursor.Division[1].Result[1].Away TYPE Name;
CREATE LASTCHILD OF cursor.Division[1].Result[1].Away NAME 'Team' VALUE 'Everton';
CREATE LASTCHILD OF cursor.Division[1].Result[1].Away NAME 'Score' VALUE '0';
CREATE FIELD cursor.Division[1].Result[2].Number TYPE NameValue VALUE '2';
CREATE FIELD cursor.Division[1].Result[2].Home TYPE Name;
CREATE LASTCHILD OF cursor.Division[1].Result[2].Home NAME 'Team' VALUE 'Manchester United';
CREATE LASTCHILD OF cursor.Division[1].Result[2].Home NAME 'Score' VALUE '2';
CREATE FIELD cursor.Division[1].Result[2].Away TYPE Name;
CREATE LASTCHILD OF cursor.Division[1].Result[2].Away NAME 'Team' VALUE 'Arsenal';
CREATE LASTCHILD OF cursor.Division[1].Result[2].Away NAME 'Score' VALUE '3';
CREATE FIELD cursor.Division[2].Number TYPE NameValue VALUE '2';
CREATE FIELD cursor.Division[2].Result[1].Number TYPE NameValue VALUE '1';
CREATE FIELD cursor.Division[2].Result[1].Home TYPE Name;
CREATE LASTCHILD OF cursor.Division[2].Result[1].Home NAME 'Team' VALUE 'Port Vale';
CREATE LASTCHILD OF cursor.Division[2].Result[1].Home NAME 'Score' VALUE '9' ;
CREATE FIELD cursor.Division[2].Result[1].Away TYPE Name;
CREATE LASTCHILD OF cursor.Division[2].Result[1].Away NAME 'Team' VALUE 'Brentford';
CREATE LASTCHILD OF cursor.Division[2].Result[1].Away NAME 'Score' VALUE '5';
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;