Developer

Handle DOM streaming protocols with the Remote Events for XML (REX) 1.0 specification

The Remote Events for XML (REX) specification introduced by the World Wide Web Consortium (W3C) defines an XML syntax for the transmission of Document Object Model (DOM) events that are compatible with streaming protocols.

The Remote Events for XML (REX) specification defines an XML syntax for the transmission of Document Object Model(DOM) events in such a way as to be compatible with streaming protocols. It enables one endpoint to interact remotely with another endpoint holding a DOM representation by sending it DOM events as if they had occurred directly at the same location. REX is useful in a variety of situations including setting an attribute of an XML element, inserting an element or even a whole hierarchy, removing an element or a tree chunk, replacing an element or the entire document, etc.

Originally the specification deliberately restricted itself to the transmission of mutation events so as to remain limited in scope and to allow for progressive enhancements to implementations over time. Restricted scope eliminated the requirement for a large specification to be deployed at once. However, the framework recently introduced by the World Wide Web Consortium (W3C) is compatible with the transmission of any other event type, and great care has been taken to ensure its extensibility and evolution.

The REX message structure

The root container element for the REX message is <rex> and it must be present always, even if there is only one <event> element. The namespace for the REX language is http://www.w3.org/2006/rex. The <rex> element can have an optional attribute version, which indicates the minimum version of the REX specification required to usefully process this message. If the version number is not in the list of versions supported by the user-agent, the user-agent will reject the message completely and immediately, ignoring the entirety of its content.

Another optional attribute is ns. It defines the namespace that applies to DOM event names within the scope of the element on which it occurs. For any given DOM event name, if there is no ns attribute on any of its ancestor elements, that event name's IRI component is http://www.w3.org/2001/xml-events. Otherwise, it will have the namespace component corresponding to the first ns attribute found on its ancestor elements in reverse document order.

In this example a tree structure is inserted into 7th position of an HTML table (Listing A - example1.xml):

Listing A - example1.xml


<rexxmlns='http://www.w3.org/2006/rex'>
  <event target='/html/body/table[2]' name='DOMNodeInserted' position='7'>
    <trxmlns='http://www.w3.org/1999/xhtml'>
      <td>Cell 1</td>
      <td>Cell 2</td>
      <td>Cell 3</td>
    </tr>
  </event>
</rex>

The <event>element is used to encode any kind of event that may be captured in REX. While the name and target attributes must always be specified, the rest of its content model depends on the event that it captures. Each <event> element must produce at least one corresponding DOM event (and on some occasions a modification of the DOM tree).

The attribute name contains the local name component of the name of the event represented by this <event> element. The namespace IRI component of the event's name must be resolved based on the ns attribute. The target attribute contains the target path, its semantics will be discussed below. It can also have a timeStamp attribute which contains an integer in milliseconds relative to the epoch (defined to be 00:00:00 UTC 1st January 1970) at which the event is to be dispatched.

The structure is simple, isn't it?

How it works

Target nodes are referenced using a very simply subset of XPath that corresponds to the level of expressivity that meets most needs while at the same time remaining easy to implement. There is never a need to resolve a relative path as they are always anchored either at the root (absolute paths) or at an element ID. The result of evaluating the target path against the target document is a node-set, ordered according to the axes used in the target path, as per XPath. Note however that the limited set of axes available in this subset will always cause the node-set to be in document order.

If the size of the node-set is superior to one, the event will be dispatched in the exact same way to each node in the node-set in order, exactly as if the <event> element had been copied multiple times in a row in the REX message, and each had had its target path modified to match only the corresponding node in the node-set.

There are a few general ideas in reduced Xpath grammar. Target paths may only begin at the root or with an id() function. The id() function itself is limited to a single string argument, which in turn must contain exactly one identifier (as opposed to a white space separated list in XPath). Only abbreviated axes are supported in the syntax. Following the beginning of the path may be a list of steps making use of either child axis, which itself may only use element name tests. The final step in the list is more powerful and may also reference text and attribute nodes. For each step a predicate may be used, which is limited to an integer indicating position.

Some examples of target paths include:

  • /svg:svg will match the root svg element, in the namespace that has been bound to the 'svg' prefix.
  • /lodges/donkey[8] will match the eighth donkey element in the lodges element with no namespace.
  • / will match the root node, which is to say the document itself.
  • /foo/text() will match all text nodes that are children of the foo element.
  • /xhtml:html/xhtml:body/svg:svg[3]/@width will match the width attribute of the third svg element that is a child of the root body and then HTML elements.
  • id("dahut") will match the element with ID 'dahut'.
  • id("dahut")/svg:circle/@cx will match the cx attribute of all the circle elements that are children of the element with ID 'dahut'.

Note that it is possible using this syntax to produce target paths that will never match anything (for instance /element[2]). Such constructions simply cause the event to be ignored. Listing B is an example of REX message with different targets (Listing B - example2.xml):

Listing B - example2.xml


<rexxmlns='http://www.w3.org/2006/rex'
     xmlns:svg='http://www.w3.org/2000/svg'>

  <event target='id("shiny-donkey")' name='DOMNodeRemoved'/>
  <event target='/svg:svg/svg:g[5]/svg:a[2]' name='activate'/>
  <event target='/svg:svg/svg:g[7]' name='DOMNodeInserted' position='9'>
    <svg:rect x='9' y='42' width='432' height='217' fill='red'/>
  </event>
  <event target='id("dahut")' name='DOMNodeRemoved'>
    <svg:circlecx='19' cy='17' r='42' fill='orange'/>
  </event>
</rex>

Generally it is recommended for implementations that REX messages be processed in a streaming fashion, so that the user-agent is not required to build a tree representation of the message. This is of particular importance in that a single REX message may capture a very long list of individual events over a long period of time, which would cause the resulting tree to consume potentially large amounts of memory.

There is no requirement on the user-agent to support a DOM interface in order to still implement events received through REX messages. For instance, specifications such as SMIL or XML Events may be handling events received through REX messages in the absence of a DOM representation of the document tree.

In order for REX to be extensible, it is necessary to define a strict extensibility model that allows future versions to introduce new constructs into messages that will still be understood to the best of their abilities by older user-agents. A REX message that is intended to be understood if and only if the user-agent supports a minimal version of the REX specification must set the "version" attribute correspondingly.

All mutation events are in the http://www.w3.org/2001/xml-events namespace. Only the following events are supported by REX specification: DOMNodeInserted, DOMNodeRemoved, DOMAttrModified and DOMCharacterDataModified. Mutation events are specific in REX processing in that they cause the DOM tree to be modified. When a user-agent processes a mutation event received in a REX message, in addition to dispatching the event it must also modify the tree (either before or after the event, as specified depending on the event type) according to the event type.

The DOMNodeInserted event indicates that a node has been inserted into the DOM tree. There is an optional attribute "position" specifying the position at which the payload must be inserted in the target element's child nodes such that a hypothetical call to parent.childNodes.item(position) would return the first node of the payload. If position is not specified, or if the specified value is higher than the number of items or lower than zero then the nodes must be inserted at the end of the list of child nodes.

Work in progress

The REX specification is still a working draft but should be considered to be a main standardized XML update mechanism. There have been similar proposals in the past, such as the XUpdate language of XML:DB initiative, and it was very influential in REX's technical design since it has been a major de facto solution since 2000.

Another initiative of the W3C related to XML events is the XML Events recommendation issued in 2003 which provides XML languages with the ability to uniformly integrate event listeners and associated event handlers with Document Object Model (DOM) Level 2 event interfaces. The result provided an interoperable way of associating behaviors with document-level markup. REX is a complementary standard representing events primarily for purposes of transmission.

Editor's Picks

Free Newsletters, In your Inbox