WebSphere Message Brokers
File: ak04950_
Writer: Bill Oppenheimer

Reference topic

This build: July 31, 2007 21:31:24

CREATE statement

The CREATE statement creates a new message field.

Syntax

Notes:
  1. Do not use the DomainClause and ParseClause with the FIELD qualifier.
  2. Use the RepeatClause only with the PREVIOUSSIBLING and NEXTSIBLING qualifiers
  3. Each subclause within the ParseClause can occur once only.

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 specified by target is navigated to (creating the fields if necessary) and any values clause or from clause is executed. This form of CREATE statement does not necessarily create any fields at all; it ensures only that the given fields do exist.

If you use array indices in the target field reference, only one instance of a particular field can be created. Thus, if you write a SET statement starting:
 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 specified by target is navigated to (creating the fields if necessary) in exactly 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). This form of CREATE statement 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 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 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 specified by target. When creating 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. This is useful because you probably 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 supplied is a zero-length character string, a new parser of the same type as the parser that owns the field 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:

Use the REPEAT clause to copy the new field's type and name from the target field. Alternatively, the new field's type, name, and value can be:
  • 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)
In the case of the FROM and PARSE clauses, you can also create children of the new field.

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:

The NAMES clause takes any expression that returns a non-null value of type character. The meaning depends on the presence of NAME and NAMESPACE clauses as follows:
NAMESPACE NAME Element named as follows
No No The element is nameless (name flag 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 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 references). For example:

	IDENTITY (XMLNS.attribute)Space1:Name1[42]

See the Examples section below for 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 could already exist in the case of a FIELD clause), and the new field is given copies of the source field's children, grandchildren, and so on.

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 doing this 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) using that mode.

When you use the PARSE clause, specify a scalar value containing the bitstream to be parsed for BitStreamExpression. If you use a message tree field reference you must ensure it contains a scalar value that contains the bitstream. An existing message body folder such as InputRoot.XMLNSC does not contain a bitstream and therefore you cannot use this to serialize the XMLNS folder. If you pass a value other than a scalar containing the bitstream to the PARSE clause for BitStreamExpression, then 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.

The following example shows how to serialize the XMLNSC folder and then use the result of the ASBITSTREAM in 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, refer to Specifying namespaces in a Message Type.

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.

Once generated, the value becomes an integer and you can save it in a variable or pass it as a parameter to a function, as well as using it directly with a CREATE statement. The list of globally defined constants is:
        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 value constraints options...
        ValidateFullConstraints
        ValidateBasicConstraints

        Validate fix up options...
        ValidateFullFixUp
        ValidateNoFixUp

        Parse timing options...
        ParseComplete
        ParseImmediate
        ParseOnDemand
Notes:
  1. The validateFullFixUp option is reserved for future use. Selecting validateFullFixUp gives identical behavior to validateNoFixUp.
  2. The validateFullConstraints option is reserved for future use. Selecting validateFullConstraints gives identical behavior to validateBasicConstraints.
  3. For full details of the validation options, refer to Validation properties.
  4. The Validate timing options correspond to Parse Timing options and, in particular, Validate Deferred is called On Demand.

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.

The ENCODING clause accepts any expression that returns a value of type integer. However, it is only meaningful to generate option values from the list of supplied constants:
       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.

When any expressions have been evaluated, a bit stream is parsed using the results of the expressions.
Note: Because this function has a large number of clauses, an alternative syntax is supported, in which the parameters are supplied as a comma-separated list rather than by named clauses. In this case the expressions must be in the order:
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

  1. The following example creates the specified field:
    CREATE FIELD OutputRoot.XMLNS.Data;
  2. The following example creates a field with no name, type, or value as the first child of ref1:
    CREATE FIRSTCHILD OF ref1;
  3. The following example creates a field using the specified type, name, and value:
    CREATE NEXTSIBLING OF ref1 TYPE NameValue NAME 'Price' VALUE 92.3;
  4. 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';
  5. 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';
  6. 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;
  7. 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);
  8. 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 sequence of statements 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>
  9. 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);

An example of a CREATE statement

This example provides sample ESQL and an input message, which together produce the output message at the end of the example.

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;
Related concepts
ESQL overview
Specifying namespaces in a Message Type
Multipart messages
Related tasks
Developing ESQL
Working with XML messages and bit streams
Related reference
Syntax diagrams: available types
ESQL statements
ASBITSTREAM function
Notices | Trademarks | Downloads | Library | Support | Feedback

Copyright IBM Corporation 1999, 2007Copyright IBM Corporation 1999, 2007. All Rights Reserved.
This build: July 31, 2007 21:31:24

ak04950_ This topic's URL is: