Manipulating messages using the XMLNSC parser

The XMLNSC domain is an extension of the XMLNS domain, which in turn, was an extension of the original XML domain.

The intent with the XMLNS domain was to add namespace support and, for compatibility reasons, a new domain was created so that existing applications would not be affected. The intent with the new XMLNSC domain is to build a more compact tree and, therefore, use less memory when handling large messages. Again, for compatibility reasons, a new domain has been added so that existing applications are not affected.

Message tree structure

The XMLNSC parser obtains its more compact tree by using a single name-value element to represent tagged text, rather than the separate name and value elements used by the XML and XMLNS parsers. Consider the following message:
    <Folder1>
        <Folder2 Attribute1='AttributeValue1'>
            <Field1><Value1></Field1>
            <Field2 Attribute2='AttributeValue2'><Value2></Field2>  
        </Folder2> 
    </Folder1>

In the XMLNSC domain, this is represented by two name elements (Folder1 and Folder2) and four name-value elements which are Attribute1, Field1, Field2, and Attribute2.

The XML and XMLNS domains differ in that the two fields are each represented by a name element with a child value element. This might seem to be a small difference, but messages often have many such leaf fields; for example:
    <Folder1>
        <Folder2>
            <Field1><Value1></Field1>
            <Field2><Value2></Field2>
            ....
            <Field100><Value100></Field100>
        </Folder2> 
    </Folder1>

In this case, the XMLNSC parser represents the message by two name and 100 name-value elements, whereas the XML and XMLNS parsers would use 102 name elements and 100 value elements, plus a further 103 value elements to represent the white-space implicit in formatted messages.

Attributes and tagged text

As both attributes and tagged text are represented by name-value elements, they are distinguished by the use of the element types. If you do not specify a type, tagged text is assumed. Therefore, the first example message above might be produced by the SQL statements:
    SET Origin.Folder1.Folder2.(XMLNSC.Attribute)Attribute1 = 
       'AttributeValue1';
    SET Origin.Folder1.Folder2.Field1 = ‘Value1’;
    SET Origin.Folder1.Folder2.(XMLNSC.Attribute)Attribute2 = 
       'AttributeValue2';
    SET Origin.Folder1.Folder2.Field2 = ‘Value2’;

Although the preceding SQL looks almost identical to that which would be used with the XML parser, note particularly that the type constants being used are ones that belong to the XMLNSC parser. The use of constants that belong to other parsers, for example XML, leads to unexpected results because similarly named constants, for exampleXML.Attribute, have different values.

Handling mixed text

By default, mixed text is simply discarded on the grounds that, if present, it is simply formatting and has no meaning.

However, a mode is provided in which, when parsing, any text that occurs other than between an opening tag and a closing tag (that is, open->open, close->close, and close->open) is represented by a single Value element. The value element types support PCDATA, CDATA, and hybrid which is a mixture of the preceding two.

There is still no special syntax element behavior regarding the getting and setting of values. Value elements can only be accessed from the SQL by explicitly addressing them. The following extra constants are provided for this purpose:
   XMLNSC.Value
   XMLNSC.PCDataValue
   XMLNSC.CDataValue
   XMLNSC.HybridValue
The mode is controlled by new message option values. For this purpose, the following constants are provided:
   XMLNSC.MixedContentRetainNone = 0x0000000000000000
   XMLNSC.MixedContentRetainAll  = 0x0001000000000000
These constants can be used in the Option clauses of both the SQL CREATE statement (PARSE section) and the ASBITSTREAM function. For example:
   DECLARE X BLOB ASBITSTREAM(InputRoot.XMLNSC.Data OPTIONS 
   XMLNSC.MixedContentRetainAll);
   ...
   CREATE LASTCHILD OF outputRoot PARSE(X OPTIONS 
   XMLNSC.MixedContentRetainNone);

Handling comments

By default, comments are also simply discarded on the grounds that, if present, they are simply auxiliary information with no meaning.

However, a mode is provided in which, when parsing, any comments that occur in the document (other than in the document description itself) are represented by a name-value element with the name Comment. The following extra comment is provided for this purpose.
   XMLNSC.Comment
The mode is controlled by new message option values. The following constants are provided for this purpose:
   XMLNSC.CommentsRetainNone = 0x0000000000000000
   XMLNSC.CommentsRetainAll  = 0x0002000000000000
For example:
   DECLARE X BLOB ASBITSTREAM(InputRoot.XMLNSC.Data OPTIONS 
   XMLNSC.CommentsRetainAll);
   ...
   CREATE LASTCHILD OF outputRoot PARSE(X OPTIONS XMLNSC.CommentsRetainNone);

Handling processing instructions

By default, processing instructions are also simply discarded on the grounds that, if present, they are simply auxiliary information with no meaning.

However, a mode is provided in which when parsing, any processing instructions that occur in the document (other than in the document description itself) are represented by a name-value element with the appropriate name and value. The following extra constant is provided for this purpose:
    XMLNSC.ProcessingInstruction
The mode is controlled by new message option values. The following constants are provided for this purpose:
    XMLNSC.ProcessingInstructionsRetainNone = 0x0000000000000000
    XMLNSC.ProcessingInstructionsRetainAll  = 0x0004000000000000
For example:
    DECLARE X BLOB ASBITSTREAM(InputRoot.XMLNSC.Data 
    OPTIONS XMLNSC.ProcessingInstructionsRetainAll);
    ...
    CREATE LASTCHILD OF outputRoot PARSE(X OPTIONS 
    XMLNSC.ProcessingInstructionsRetainNone);

Migrating an existing flow

The fact that a new domain has been introduced means that, when using the XMLNSC parser, you must re-code your ESQL to use XMLNSC in your paths. Consider the following examples:
SET OutputRoot.XML.Person.Salary    = 
               CAST(InputRoot.XML.Person.Salary AS INTEGER) * 3;
SET OutputRoot.XMLNS.Person.Salary  = 
               CAST(InputRoot.XMLNS.Person.Salary AS INTEGER) * 3;
SET OutputRoot.XMLNSC.Person.Salary = 
               CAST(InputRoot.XMLNSC.Person.Salary AS INTEGER) * 3;
In each case the XML bit-stream expected at the input queue and written to the output queue is of the form:
    <Person><Salary>42</Salary></Person>

The three cases differ in that they are using different parsers to own these elements. Therefore, a different domain name is expected in the MQRFH2 header of the incoming message and a different domain name is written in the MQRFH2 header of the outgoing message.

To protect external applications from these changes, the Use XMLNSC Compact Parser for XMLNS Domain property can be specified on the flow's input node, and on the compute node containing these statements.

The first example causes the XMLNSC parser to be used to parse the body of the message when the MQRFH2 header in the incoming message specifies the XMLNS domain; that on the compute node causes the outgoing MQRFH2 to specify the XMLNS instead of XMLNSC parser, so allowing the input and output messages to remain unchanged.

If the incoming messages do not contain MQRFH2 headers, and the input node's message domain attribute is being used to specify the domain, you can either set it to XMLNSC, or set it to XMLNS and also set the Use XMLNSC Compact Parser for XMLNS Domain property.

If outgoing messages do not contain MQRFH2 headers, the domain does not appear anywhere in the output messages and the setting of the compute node's Use XMLNSC Compact Parser for XMLNS Domain property has no effect

Constructing XML headers

The following ESQL is valid in the XML domain:
SET OutputRoot.XML.(XML.XmlDecl)*.(XML.Version)* = '1.0';
To migrate to XMLNS, simply changing the root is enough to make this work:
SET OutputRoot.XMLNS.(XML.XmlDecl)*.(XML.Version)* = '1.0';

Note that although the XMLNS parser is being used, the element type constants are those belonging to the XML parser. This works because the type values used by the XML and XMLNS parsers are the same. For the XMLNSC parser, however, the type values are different and, therefore, you must always use its own type constants.

In the XMLNSC domain there is no special type for theXML version; it is simply treated as an attribute of the XML declaration. The equivalent syntax for the above example is:
SET OutputRoot.XMLNSC.(XMLNSC.XmlDeclaration)*.(XMLNSC.Attribute)Version = '1.0';

Copying message trees

When copying trees, the broker regards XML and XMLNSC as unlike parsers, which means that all attributes in the source tree get mapped to elements in the target tree. This situation arises only if you are using both parsers in the same flow - one for input and one for output; you are therefore recommended to use the compact parser for both flows.

If different parsers must be used for the input flow and output flow , you might need to explicitly specify the types of elements in the paths or use the FIELDVALUE function to ensure a copy of scalar values rather than of sub-trees.

Follow the guidance provided for XML messages in Manipulating messages in the XML domain, in conjunction with the information in the topic Manipulating message body content.

Accessing syntax elements in the XMLNSC domain using correlation names

The following table provides the correlation names for each XML syntax element. When working in the XMLNSC domain, use these names to refer to the elements in input messages, and to set elements, attributes, and values in output messages.
Table 1. Correlation names for XML syntax elements
Syntax element Correlation name Constant value
Folder XMLNSC.Folder 0x01000000
Document type 1 XMLNSC.DocumentType 0x01000300
XML declaration 2 XMLNSC.XmlDeclaration 0x01000400
     
Field or Attr Value XMLNSC.Value 0x02000000
PCData value XMLNSC.PCDataValue 0x02000000
CData value XMLNSC.CDataValue 0x02000001
Hybrid value XMLNSC.HybridValue 0x02000002
     
Entity Reference XMLNSC.EntityReference 0x02000100
     
Field XMLNSC.Field 0x03000000
PCData XMLNSC.PCDataField 0x03000000
CData XMLNSC.CDataField 0x03000001
Hybrid XMLNSC.HybridField 0x03000002
     
Attribute XMLNSC.Attribute 0x03000100
Single quote XMLNSC.SingleAttribute 0x03000101
Double quote XMLNSC.DoubleAttribute 0x03000100
     
Namespace declaration XMLNSC.NamespaceDecl 0x03000102
Single quote XMLNSC.SingleNamespaceDecl 0x03000103
Double quote XMLNSC.DoubleNamespaceDecl 0x03000102
     
Bitstream data XMLNSC.BitStream 0x03000200
     
Entity definition 1 XMLNSC.EntityDefinition 0x03000300
Single quote XMLNSC.SingleEntityDefinition 0x03000301
Double quote XMLNSC.DoubleEntityDefinition 0x03000300
     
Comment XMLNSC.Comment 0x03000400
     
Processing instruction XMLNSC.ProcessingInstruction 0x03000401
Notes:
  1. Document Type is only used for entity definitions. For example:
    SET OutputRoot.XMLNSC.(XMLNSC.DocumentType)BodyDocument
                  .(XMLNSC.EntityDefinition)TestDef =
     		          'Compact Tree Parser XML Test Module Version 1.0';
  2. Note that the XML declaration is a special folder type that contains child elements for version, and so on. For example:
    -- Create the XML declaration 		
    SET OutputRoot.XMLNSC.(XMLNSC.XmlDeclaration)*.Version = 1.0;
    SET OutputRoot.XMLNSC.(XMLNSC.XmlDeclaration)*.Encoding = 'UTF8';
    SET OutputRoot.XMLNSC.(XMLNSC.XmlDeclaration)*.Standalone = 'yes';

XMLNSC parser modes

By default, the XMLNSC parser discards document elements that typically carry no business meaning. However, parser modes are available to force retention of these elements. You can configure these modes on the properties of the node that specifies the message is to be parsed in the XMLNSC domain.

The valid parser modes for the XMLNSC parser are:
XMLNSC.MixedContentRetainNone
XMLNSC.MixedContentRetainAll
XMLNSC.CommentsRetainNone
XMLNSC.CommentsRetainAll
XMLNSC.ProcessingInstructionsRetainNone
XMLNSC.ProcessingInstructionsRetainAll
The following example uses the XMLNSC.ProcessingInstructionsRetainAll and XMLNSC.ProcessingInstructionsRetainNone modes to retain document processing instructions while parsing:
DECLARE X BLOB ASBITSTREAM(InputRoot.XMLNSC.Data OPTIONS XMLNSC
                          .ProcessingInstructionsRetainAll);
...     
CREATE LASTCHILD OF outputRoot PARSE(X OPTIONS XMLNSC
                          .ProcessingInstructionsRetainNone);
Related concepts
Message flows overview
XML parsers and domains
ESQL overview
Related tasks
Designing a message flow
Defining message flow content
Manipulating messages in the XML domain
Related reference
ESQL reference
SET statement
FIELDVALUE function
ASBITSTREAM function
CREATE statement