Extracting information from a message by using XPath 1.0 and a JavaCompute node

XPath is a query language designed for use with XML documents, but you can use it with any tree structure to query contents.

IBM® Integration Bus uses XPath to select elements from the logical message tree regardless of the format of the bit stream. The terminology used in this topic is based on the terminology used in the W3C definition of XPath 1.0. For more information about XPath, see Using XPath; and for more information about the W3C definition of the XPath 1.0 standard, see W3C XPath 1.0 Specification. For examples of XPath use, see the MbXPath topic in the Java user-defined node API documentation.

Using the evaluateXPath method to extract message information

The evaluateXPath() method is included in the Java user-defined node API. It supports XPath 1.0, with the following exceptions:
  • Namespace axis and namespace node type. The namespace axis returns the actual XML namespace declaration nodes for a particular element. You can therefore manipulate XML prefix or URI declarations within an XPath expression. This axis returns an empty node set for bit streams that are not XML.
  • If you use the id() function, it throws an MbRecoverableException.

The evaluateXPath() method can be called on a MbMessage object (for absolute paths), or on a MbElement object (for relative paths). The XPath expression is passed to the method as a string parameter. A second form of this method is provided that takes an MbXPath object. This object encapsulates an XPath expression along with variable bindings and namespace mappings, if these are required.

The evaluateXPath() method returns an object of one of these four types, depending on the expression return type:
  • java.lang.Boolean, representing the XPath Boolean type
  • java.lang.Double, representing the XPath number type
  • java.lang.String, representing the XPath string type
  • java.util.List, representing the XPath node set. The List interface represents an ordered sequence of objects, in this case MbElements. It allows direct access to the elements, or the ability to get an Iterator or an MbElement array.

XPath variable binding

XPath 1.0 supports the ability to refer to variables that have been assigned before the expression that contains them is evaluated. The MbXPath class has three methods for assigning and removing these variable bindings from user Java code. The value must be one of the four XPath 1.0 supported types:
  • Boolean
  • node set
  • number
  • string

XPath namespace support

For XML messages, namespaces are referred to by using a mapping from an abbreviated namespace prefix to the full namespace URI, as shown in the following XML example:
<ns1:aaa xmlns:ns1='http://mydomain.com/namespace1'
         xmlns:ns2='http://mydomain.com/namespace2'>
  <ns2:aaa>
    <ns1:bbb/>
  </ns2:aaa>
</ns1:aaa>

The namespace prefix is convenient for representing the namespace, but is meaningful only within the document that defines that mapping. The namespace URI defines the global meaning. Also, the concept of a namespace prefix is not meaningful for documents that are generated in a message flow, because a namespace URI can be assigned to a syntax element without an XMLNS mapping having been defined.

For this reason, the XMLNSC and MRM parsers expose only the namespace URI to the integration node and to user code (ESQL or user-defined code). By using ESQL, you can set up your own mappings to create abbreviations to these potentially long URIs. These mappings are not related in any way to the prefixes that are defined in the XML document (although they can be the same name).

By using the XPath processor you can map namespace abbreviations on to URIs that are expanded at evaluation time. The MbXPath class contains methods to assign and remove these namespace mappings. For example:
MbNamespaceBindings ns = new MbNamespaceBindings();
ns.addBinding("other", "http://mydomain.com/namespace2");
ns.setDefaultNamespace("http://mydomain.com/namespace2");
MbXPath xp = new MbXPath("/aaa/other:aaa/bbb", ns);
List<MbElement> nodeset = (List<MbElement>)message.evaluateXPath(xp);

Updating a message by using XPath extensions

The XPath implementation in IBM Integration Bus provides the following extra functions for modifying the message tree:
set-local-name(object)
Sets the local part of the expanded name of the context node to the value specified in the argument. object can be any valid expression, and is converted to a string as if a call to the string function is used.
set-namespace-uri(object)
Sets the namespace URI part of the expanded name of the context node to the value specified in the argument. object can be any valid expression, and is converted to a string as if a call to the string function is used.
set-value(object)
This function sets the string value of the context node to the value specified in the argument. object can be any valid expression, and is converted to a string as if a call to the string function is used.
To allow for syntax element trees to be built as well as modified, the following axis is available in addition to the 13 that are defined in the XPath 1.0 specification:
select-or-create::name or ?name
?name is equivalent to select-or-create::name. If name is @name, an attribute is created or selected. This selects child nodes matching the specified name, or creates new nodes according to the following rules:
  • ?name selects children called name if they exist. If a child called name does not exist, ?name creates it as the last child, then selects it.
  • ?$name creates name as the last child, then selects it.
  • ?^name creates name as the first child, then selects it.
  • ?>name creates name as the next sibling, then selects it.
  • ?<name creates name as the previous sibling, then selects it.