Accessing attributes and elements
The XMLNS parser sets the field type on every message tree element that it creates.
The field type indicates the type of XML construct that the element represents. The field types used by the XMLNS parser can be referenced using constants with names prefixed with ‘XML.' Field type constants with prefix ‘XML.' are for use with the XMLNS and XML parsers only; they do not work with the XMLNSC or MRM parsers.
XMLNS Field Type constant | |
---|---|
Tag | XML.Element |
Attribute |
|
By using the field type in this way, the XMLNS parser can distinguish between an element and an attribute that have the same name.
Example XML
<parent id="12345">
<id>ABCDE</id>
</parent>
Example ESQL
SET value = FIELDVALUE(InputRoot.XMLNS.parent.(XML.Element)id)
Result : value is 'ABCDE'
SET value = FIELDVALUE(InputRoot.XMLNS.parent.(XML.Attr)id)
Result : value is '12345'
Example using SELECT to access multiple attributes
In
the Example message, the element Title within each
Item element has three attributes: Category, Form, and Edition. For
example, the first Title element contains:
<Title Category="Computer" Form="Paperback" Edition="2">The XML Companion</Title>
The
element InputRoot.XML.Invoice.Purchases.Item[1].Title
has
four children in the logical tree: Category, Form, Edition, and the
element value, which is "The XML Companion".If you want to
access the attributes for this element, you can code the following
ESQL. This extract of code retrieves the attributes from the input
message and creates them as elements in the output message. It does
not process the value of the element itself in this example.
-- Set the cursor to the first XML.Attribute of the Title.
-- Note the * after (XML.Attribute) meaning any name, because the name might not be known
DECLARE cursor REFERENCE TO InputRoot.XMLNS.Invoice.Purchases.Item[1].Title.(XML.Attribute)*;
WHILE LASTMOVE(cursor) DO
-- Create a field with the same name as the XML.Attribute
-- and set its value to the value of the XML.Attribute
SET OutputRoot.XML.Data.Attributes.{FIELDNAME(cursor)} = FIELDVALUE(cursor);
-- Move to the next sibling of the same TYPE to avoid the Title value
-- which is not an XML.Attribute
MOVE cursor NEXTSIBLING REPEAT TYPE;
END WHILE;
When this ESQL is processed by the Compute node, the following
output message is generated:
<Data>
<Attributes>
<Category>Computer</Category>
<Form>Paperback</Form>
<Edition>2</Edition>
</Attributes>
</Data>
You can also use a SELECT statement:
SET OutputRoot.XMLNS.Data.Attributes[] =
(SELECT FIELDVALUE(I.Title) AS title,
FIELDVALUE(I.Title.(XML.Attribute)Category) AS category,
FIELDVALUE(I.Title.(XML.Attribute)Form) AS form,
FIELDVALUE(I.Title.(XML.Attribute)Edition) AS edition
FROM InputRoot.XML.Invoice.Purchases.Item[] AS I);
This
statement generates the following output message:<Data>
<Attributes>
<title>The XML Companion</title>
<category>Computer</category>
<form>Paperback</form>
<edition>2</edition>
</Attributes>
<Attributes>
<title>A Complete Guide to DB2 Universal Database</title>
<category>Computer</category>
<form>Paperback</form>
<edition>2</edition>
</Attributes>
<Attributes>
<title>JAVA 2 Developers Handbook</title>
<category>Computer</category>
<form>Hardcover</form>
<edition>0</edition>
</Attributes>
</Data>
You can qualify the SELECT with a WHERE
statement to narrow down the results to obtain the same output message
as the one that is generated by the WHILE statement. This second example
shows that you can create the same results with less, and less complex,
ESQL.
SET OutputRoot.XMLNS.Data.Attributes[] =
(SELECT FIELDVALUE(I.Title.(XML.Attribute)Category) AS category,
FIELDVALUE(I.Title.(XML.Attribute)Form) AS form,
FIELDVALUE(I.Title.(XML.Attribute)Edition) AS edition
FROM InputRoot.XML.Invoice.Purchases.Item[] AS I)
WHERE I.Title = 'The XML Companion');
This statement
generates the following output message:<Data>
<Attributes>
<Category>Computer</Category>
<Form>Paperback</Form>
<Edition>2</Edition>
</Attributes>
</Data>