You can use ESQL field references to form paths to message body elements.
>>-CorrelationName--+---------------------+-------------------->< | .-.---------------. | | V | | '---| PathElement |-+-' PathElement |--+------------+-----------------------------------------------> '-(--Type--)-' >-- ---+----------------------------------+--+-Name-----------------+--> '-+---------------------------+--:-' +-{--NameExpression--}-+ +-Namespace-----------------+ '-*--------------------' +-{--NamespaceExpression--}-+ '---*-----------------------' >--+------------------------+-----------------------------------| '-[--+--------------+--]-' +-Index--------+ +-<--+-------+-+ | '-Index-' | +->--+-------+-+ | '-Index-' | '-<------------'
A field reference consists of a correlation name, followed by zero or more Path Elements separated by periods (.). The correlation name identifies a well-known starting point and must be the name of a constant, a declared variable (scalar, row or reference), or one of the predefined start points; for example, InputRoot. The path Fields define a path from the start point to the desired field.
InputRoot.XMLNS.Data.Invoice
starts
the broker at the location InputRoot (that is, the root of the input
message to a Compute node) and then performs a sequence of navigations.
First, it navigates from root to the first child field called XMLNS,
then to the first child field of the XMLNS field called Data. Finally,
the broker navigates to the first child field of the Data field called
Invoice. Whenever this field reference occurs in an ESQL program,
the invoice field is accessed.InputRoot.XMLNS."Customer Data".Invoice
If
you need to refer to fields that contain quotation marks, use two
pairs of quotation marks around the reference. For example: Body.Message."""hello"""
Some identifiers are reserved as keywords but, with the exception of the correlation name, you can use them in field references without the use of double quotation marks
InputRoot.XMLNS."Customer Data".{'Customer-' ||
CurrentCustomer}.Invoice
in which the invoices are contained
in a folder with a name is formed by concatenating the character literal
Customer- with the value in CurrentCustomer (which in this example
must be a declared variable of type character). InputRoot.XMLNS.*.Invoice.Value
matches
any path element in which the invoices are contained.Note that enclosing anything in double quotation marks in ESQL makes it an identifier; enclosing anything in single quotation marks makes it a character literal. You must enclose all character strings in single quotation marks.
DECLARE sp1 NAMESPACE 'http://www.ibm.com/space1';
/* Namespace declaration to associate prefix 'space1' with the namespace */
SET OutputRoot.XMLNS.TestCase.(XML.NamespaceDecl)xmlns:space1 = 'http://www.ibm.com/space1';
SET OutputRoot.XMLNS.TestCase.sp1:data1 = 'Hello!';
generates:<TestCase xmlns:space1="http://www.ibm.com/space1">
<space1:data1>Hello!</space1:data1>
</TestCase>
InputRoot.XMLNS.Data[1].Invoice
InputRoot.XMLNS.Data.Invoice[1]
This construct is most
commonly used with an index variable, so that a loop steps though
all such fields in sequence. For example: WHILE count < 32 DO
SET TOTAL = TOTAL + InputRoot.XMLNS.Data.Invoice[count].Amount;
SET COUNT = COUNT + 1
END WHILE;
Use this kind of construct with care, because
it implies that the broker must count the fields from the beginning
each time round the loop. If the repeat count is large, performance
will be poor. In such cases, a better alternative is to use a field
reference variable.InputRoot.XMLNS.Data.Invoice -- Selects the first
InputRoot.XMLNS.Data.Invoice[1] -- Selects the first
InputRoot.XMLNS.Data.Invoice[>] -- Selects the first
InputRoot.XMLNS.Data.Invoice[>1] -- Selects the first
InputRoot.XMLNS.Data.Invoice[>2] -- Selects the second
InputRoot.XMLNS.Data.Invoice[<] -- Selects the fourth
InputRoot.XMLNS.Data.Invoice[<1] -- Selects the fourth
InputRoot.XMLNS.Data.Invoice[<2] -- Selects the third
InputRoot.XMLNS.Data.Invoice[<3] -- Selects the second
An
index clause can also consist of an empty pair of brackets ( [] ).
This selects all fields with matching names. Use this construct with
functions and statements that expect lists (for example, the SELECT,
CARDINALITY, SINGULAR, and EXISTS functions, or the SET statement)
.Each field of a field reference can contain a type clause. These are denoted by parentheses ( ( ) ), and accept any expression that returns a non-null value of type integer. The presence of a type expression restricts the fields that are selected to those of the matching type. This construct is most commonly used with generic XML, where there are many field types and it is possible for one XML field to contain both attributes and further XML Fields with the same name.
<Item Value = '1234'>
<Value>5678</Value>
</Item>
Here, the XML field Item has two child Fields, both called "Value". The child Fields can be distinguished by using type clauses: Item.(<Domain>.Attribute)Value to select the attribute, and Item.(XML.Element)Value to select the field, where <Domain> is one of XML, XMLNS, or XMLNSC, as determined by the message domain of the source.
(1) >>-(--FieldReference--)--ScalarDataTypeName--------------------><
Typically, a type constraint causes the scalar value of the reference to be extracted (in a similar way to the FIELDVALUE function) and an exception to be thrown if the reference is not of the correct type. By definition, an exception will be thrown for all nonexistent fields, because these evaluate to NULL. This provides a convenient and fast way of causing exceptions if essential fields are missing from messages.
However, when type constraints occur in expressions that are candidates for being passed to a database (for example, they are in a WHERE clause), the information is used to determine whether the expression can be given to the database. This can be important if a WHERE clause contains a CAST operating on a database table column. In the absence of a type constraint, such expressions cannot be given to the database because the broker cannot tell whether the database is capable of performing the required conversion. Note, however, that you should always exercise caution when using casts operating on column values, because some databases have exceedingly limited data conversion capabilities.
The namespace is taken to be the only namespace in the namespace path containing this name. The only namespace that can be in the path is the notarget namespace.
These forms all existed before namespaces were introduced. Although their behavior has changed in that they now compare both name and namespace, existing transforms should see no change in their behavior because all existing transforms create their Fields in the notarget namespace.
In all the preceding cases a name, or namespace, provided by an expression contained in braces ({}) is equivalent to a name provided as an identifier.
By definition, the name of the notarget namespace is the empty string. The empty string can be selected by expressions which evaluate to the empty string, the empty identifier "", or by reference to a namespace constant defined as the empty string.
The use of field references usually implies searching for an existing field. However, if the required field does not exist, as is usually the case for field references that are the targets of SET statements and those in the AS clauses of SELECT functions, it is created.
In the absence of a type specification, the field's type is not Name or NameValue, which effectively indicates that the new field is nameless
.These defaults can be derived from field names, column names or can simply be manufactured sequence names. If the name is an field name, this is effectively a tree copy, and the namespace name is copied as above.
Otherwise, the namespace of the newly-created field is derived by searching the path, that is, the name is be treated as the NameId syntax of a field reference.
SET OutputRoot.XMLNS.Msg.Data.Name = NULL; -- this deletes the field
SET OutputRoot.XMLNS.Msg.Data.Name VALUE = NULL;
-- this assigns a NULL value to a field without deleting it
For compatibility with earlier versions, the LAST keyword is still supported, but its use is deprecated. LAST cannot be used as part of an index expression: [LAST] is valid, and is equivalent to [<], but [LAST3] is not valid.
Field [> ] -- The first field, equivalent to [ 1 ]
Field [> (a + b) * 2 ]
Field [ < ] -- The last field, equivalent to [ LAST ]
Field [ < 1 ] -- The last field, equivalent to [ LAST ]
Field [ < 2 ] -- The last but one field
Field [ < (a + b) / 3 ]