Class Hierarchy All Classes All Fields and Methods

Class com.ibm.broker.plugin.MbXPath

java.lang.Object
        com.ibm.broker.plugin.MbXPath

public class MbXPath
extends Object

XPath is a query language for addressing parts of an XML document. It navigates the hierarchical structure of a document using a directional select and predicate based syntax.

XPath, although designed for XML documents, can be applied to any tree structure for querying purposes. Within the broker it is used to select elements within the WBIMB logical message model regardless of the format of the bit stream. Care has to be taken over the difference in terminology between WBIMB and XPath. An XML node is represented in the broker by an instance of class MbElement. The broker's concept of a message flow node is not relevant to this discussion.

MbXPath provides a complete implementation of the XPath 1.0 query syntax as described in the W3C recommendation at http://www.w3.org/TR/xpath.

Namespace support

The namespace axis is not implemented exactly according to the W3C recommendation because an XPath 1.0 namespace node is a virtual node generated on the fly during evaluation to represent the namespaces in scope for an element. Since all nodes in this implementation map to an actual MbElement, this concept is not applicable to the broker. The namespace axis in this implementation will return the actual XML namespace declaration nodes for a particular element. This is included to allow users to manipulate XML prefix/URI declarations within an XPath expression.

For XML messages, namespaces are referred to using a mapping from an abbreviated namespace prefix to the full namespace URI as shown in the following XML snippet:

<aaa xmlns='http://mydomain.com/namespace1'
     xmlns:other='http://mydomain.com/namespace2'>
  <other:aaa>
    <bbb/>
  </other:aaa>
<aaa>

While the namespace prefix is convenient shorthand for representing the namespace, it is only meaningful within the document that defines that mapping. It is the namespace URI that defines the global meaning. Also the concept of namespace prefix becomes even more meaningless for documents that are generated within a message flow since a namespace URI can be assigned to a syntax element without an xmlns mapping having been defined. Although the broker only works internally with namespace URIs, the MbXPath provides the ability to map namespace prefixes to the full URIs. The prefixes in the above XML snippet could used in an XPath expression by calling the namespace mapping methods prior to evaluation:

MbXPath xp = new MbXPath("/aaa/other:aaa/bbb");
xp.addNamespacePrefix("other", "http://mydomain.com/namespace2");
xp.setDefaultNamespace("http://mydomain.com/namespace2");
List nodeset = (List)message.evaluateXPath(xp);


The broker will not use the prefixes used by the namespace declarations in the XML document and the prefixes assigned in the above method calls do not need to be the same as those in the XML namespace declarations. Also, the namespace mappings created in the MbXPath object are global mappings for the whole document rather than the structured (hierarchical) mappings of XML namespace declarations.

Limitations

The XPath 1.0 function id() is not supported and, if called, will always return an empty nodeset.

Broker extensions

The XPath 1.0 specification allows for an XPath implementation to provide additional functions on top of the compulsory core function library that are useful to the application. For example, XSLT defines extra functions relevant to its usage. The broker's XPath implementation provides the following extra functions for changing 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. The argument can be any valid expression and will be converted to a string as if by a call to the string function. This function always returns true.
set-namespace-uri(object)
sets the namespace URI part of the expanded-name of the context node to the value specified in the argument. The argument can be any valid expression and will be converted to a string as if by a call to the string function. This function always returns true.
set-value(object)
sets the string-value of the context node to the value specified in the argument. The argument can be any valid expression and will be converted to a string as if by a call to the string function. This function always returns true.
To allow for syntax element trees to be built as well as modified, a new axis is supported in addition to the 13 that are defined in the XPath 1.0 specification:
select-or-create:: (abbreviated form'?')
This will select child nodes matching the specified nametest or create new nodes according to the following rules:

?name- select children called 'name'. Create one (as last child) if none exist, then select it.
?$name- create 'name' as last child, then select it.
?^name- create 'name' as first child, then select it.
?>name- create 'name' as next sibling, then select it.
?<name- create 'name' as previous sibling, then select it.

Notes:

Broker XPath examples

Examples of XPath 1.0 usage can be found in the W3C recommendation as well as numerous books and websites. The expressions presented here demonstrate the extended syntax supported by the broker for modifying messages and creating sub-trees. The examples refer to the following XML document:

<example>
  <items>
    <item>
      <price>3.45</price>
    </item>
    <item>
      <price>6.57</price>
    </item>
    <item>
      <price>1.95</price>
    </item>
    <item>
      <price>0.50</price>
    </item>
  </items>
</example>

ExpressionResultant document
//price[set-value(. * 2)]

This expression selects all price descendants of root and doubles their value.
<example>
  <items>
    <item>
      <price>6.9</price>
    </item>
    <item>
      <price>13.14</price>
    </item>
    <item>
      <price>3.9</price>
    </item>
    <item>
      <price>1</price>
    </item>
  </items>
</example>
//price[set-local-name("cost")]

This expression selects all price descendants of root and changes their name to cost.
<example>
  <items>
    <item>
      <cost>3.45</cost>
    </item>
    <item>
      <cost>6.57</cost>
    </item>
    <item>
      <cost>1.95</cost>
    </item>
    <item>
      <cost>0.50</cost>
    </item>
  </items>
</example>
/example/?items/?$item/?price[set-value($three * 1.5)]

This expression introduces the select-or-follow axis (in the abbreviated form). items already exists, so is selected. ?$item says create item as last child of items regardless of whether one already exists. This item is selected and the ?price creates a new child under it. Finally, the value of the price element is set by evaluating the argument. The variable three was assigned the value '3' prior to evaluation using:

xp.assignVariable("three", 3);
<example>
  <items>
    <item>
      <price>3.45</price>
    </item>
    <item>
      <price>6.57</price>
    </item>
    <item>
      <price>1.95</price>
    </item>
    <item>
      <price>0.50</price>
    </item>
  <item><price>4.5</price></item></items>
</example>
(//item/?@index)[set-value(position())]

This expression selects all item descendants of root and creates a new attribute (@) called index. All index attributes are selected and grouped within the parentheses. The argument of set-value() uses the core XPath function position() which returns the position of each node within the group.
<example>
  <items>
    <item index="1">
      <price>3.45</price>
    </item>
    <item index="2">
      <price>6.57</price>
    </item>
    <item index="3">
      <price>1.95</price>
    </item>
    <item index="4">
      <price>0.50</price>
    </item>
  </items>
</example>
/example/items/?total[set-value(sum(/example/items/item/price))]

This expression creates (or selects if it already existed) the element total as last child of items and sets its value to the sum of all the price values for all items.
<example>
  <items>
    <item>
      <price>3.45</price>
    </item>
    <item>
      <price>6.57</price>
    </item>
    <item>
      <price>1.95</price>
    </item>
    <item>
      <price>0.50</price>
    </item>
  <total>12.47</total></items>
</example>

Constructor Index
Constructor Description
MbXPath(String) Creates an MbXPath object from an XPath 1.0 expression.
MbXPath(String, MbElement) Creates an MbXPath object from an XPath 1.0 expression.
Method Index
Method Description
void addNamespacePrefix(String, String) Add a mapping between a namespace prefix and the full namespace URI.
void assignVariable(String, boolean) Assigns a new value to the named external variable binding in the current object.
void assignVariable(String, double) Assigns a new value to the named external variable binding in the current object.
void assignVariable(String, Object) Assigns a new value to the named external variable binding in the current object.
void removeAllVariables() Removes the currently assigned values of all the named external variable bindings.
void removeNamespacePrefix(String) Removes the currently assigned prefix to namespace URI mapping.
void removeVariable(String) Removes the currently assigned value of the named external variable binding.
void setDefaultNamespace(String) Sets the default namespace URI for this XPath 1.0 expression.

Constructors

MbXPath

public MbXPath(String expression) throws MbException

Creates an MbXPath object from an XPath 1.0 expression. The expression may contain external variable bindings. By default the root element is the message 'Body' (i.e. last child of MbMessage root).

MbXPath

public MbXPath(String expression,
               MbElement root) throws MbException

Creates an MbXPath object from an XPath 1.0 expression. The expression may contain external variable bindings. By default the root element is the message 'Body' (i.e. last child of MbMessage root). This constructor allows the document root to be defined. Absolute path locations start at this root element.

Methods

addNamespacePrefix

public void addNamespacePrefix(String prefix,
                               String uri) 

Add a mapping between a namespace prefix and the full namespace URI.

assignVariable

public void assignVariable(String variable,
                           boolean value) 

Assigns a new value to the named external variable binding in the current object.

assignVariable

public void assignVariable(String variable,
                           double value) 

Assigns a new value to the named external variable binding in the current object.

assignVariable

public void assignVariable(String variable,
                           Object value) 

Assigns a new value to the named external variable binding in the current object.

removeAllVariables

public void removeAllVariables() 

Removes the currently assigned values of all the named external variable bindings.

removeNamespacePrefix

public void removeNamespacePrefix(String prefix) 

Removes the currently assigned prefix to namespace URI mapping.

removeVariable

public void removeVariable(String variable) 

Removes the currently assigned value of the named external variable binding.

setDefaultNamespace

public void setDefaultNamespace(String uri) 

Sets the default namespace URI for this XPath 1.0 expression.

Class Hierarchy All Classes All Fields and Methods