www.espertech.comDocumentation

Appendix I. Event Representation: org.w3c.dom.Node XML Events

This section provides information for using org.w3c.dom.Node XML to represent events.

For NEsper .NET also see Section J.9, “.NET XML Events”.

Events can be represented as org.w3c.dom.Node instances and send into the runtime via the sendEventXMLDOM method on EPEventService or via EventSender. Please note that either configuration or create xml schema with annotations are required so the event type name and root element name is known. See Section 17.4.8, “Events Represented by org.w3c.dom.Node”.

If a XML schema document (XSD file) can be made available as part of the configuration or as part of create xml schema, then the compiler and runtime can read the schema and appropriately present event type metadata and validate statements that use the event type and its properties. See Section I.2, “Schema-Provided XML Events”.

When no XML schema document is provided, XML events can still be queried, however the return type and return values of property expressions are string-only and no event type metadata is available other than for explicitly configured properties. See Section I.3, “No-Schema-Provided XML Events”.

In all cases the compiler and runtime allow you to configure explicit XPath expressions as event properties. You can specify arbitrary XPath functions or expressions and provide a property name and type by which result values will be available for use in statements. See Section I.4, “Explicitly-Configured Properties”.

Nested, mapped and indexed event properties are also supported in expressions against org.w3c.dom.Node events. Thus XML trees can conveniently be interrogated via the property expression syntax.

Only one event type per root element name may be configured.

This section uses the following XML document as an example:

<?xml version="1.0" encoding="UTF-8"?>
<Sensor xmlns="SensorSchema">
  <ID>urn:epc:1:4.16.36</ID>
  <Observation Command="READ_PALLET_TAGS_ONLY">
    <ID>00000001</ID>
    <Tag>
      <ID>urn:epc:1:2.24.400</ID>
    </Tag>
    <Tag>
      <ID>urn:epc:1:2.24.401</ID>
    </Tag>
  </Observation>
</Sensor>

The schema for the example is:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="Sensor">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="ID" type="xs:string"/>
        <xs:element ref="Observation" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="Observation">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="ID" type="xs:string"/>
        <xs:element ref="Tag" maxOccurs="unbounded" />
      </xs:sequence>
      <xs:attribute name="Command" type="xs:string" use="required" />
    </xs:complexType>
  </xs:element>

  <xs:element name="Tag">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="ID" type="xs:string"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

If you have a XSD schema document available for your XML events, the compiler and runtime can interrogate the schema. The benefits are:

The compiler reads a XSD schema file from an URL you provide. Make sure files imported by the XSD schema file can also be resolved.

The configuration and create xml schema accept a schema URL. This is a sample code snippet to determine a schema URL from a file in classpath:

URL schemaURL = this.getClass().getClassLoader().getResource("sensor.xsd");
// For NEsper .NET use C# ResourceManager class for loading resources

Here is a sample use of the configuration API, please see Chapter 17, Configuration for further examples.

ConfigurationCommonEventTypeXMLDOM sensorcfg = new ConfigurationCommonEventTypeXMLDOM();
sensorcfg.setRootElementName("Sensor");
sensorcfg.setSchemaResource(schemaURL.toString());
Configuration configuration = new Configuration();
configuration.getCommon().addEventType("SensorEvent", sensorcfg);

Here is a sample use of create xml schema.

@XMLSchema(rootElementName='Sensor', schemaResource='some url value here')
create xml schema SensorEvent()

There does not need to be a root element name. The sendEventXMLDOM(org.w3c.Node node, String eventTypeName) method accepts the event type name. An EventSender is a useful alternative method for sending events if the type lookup based on the root or document element name is not desired.

After adding the event type, you may create statements and send events. Next is a sample statement:

select ID, Observation.Command, Observation.ID, 
  Observation.Tag[0].ID, Observation.Tag[1].ID
from SensorEvent

As you can see from the example above, property expressions can query property values held in the XML document's elements and attributes.

There are multiple ways to obtain a XML DOM document instance from a XML string. The next code snippet shows how to obtain a XML DOM org.w3c.Document instance:

InputSource source = new InputSource(new StringReader(xml));
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setNamespaceAware(true);
Document doc = builderFactory.newDocumentBuilder().parse(source);

Send the org.w3c.Node or Document object into the runtime for processing:

runtime.getEventService().sendEventXMLDOM(doc, "SensorEvent");

By setting the xpath-property-expr option the compiler rewrites each property expression as an XPath expression, effectively handing the evaluation over to the underlying XPath implementation available from classpath. Most JVM have a built-in XPath implementation and there are also optimized, fast implementations such as Jaxen that can be used as well.

Set the xpath-property-expr option if you need namespace-aware document traversal, such as when your schema mixes several namespaces and element names are overlapping.

The below table samples several property expressions and the XPath expression generated for each, without namespace prefixes to keep the example simple:


For mapped properties that are specified via the syntax name('key'), the algorithm looks for an attribute by name id and generates a XPath expression as mapped[@id='key'].

Finally, here is an example that includes all different types of properties and their XPath expression equivalent in one property expression:

select nested.mapped('key').indexed[1].attribute from MyEvent

The equivalent XPath expression follows, this time including n0 as a sample namespace prefix:

/n0:rootelement/n0:nested/n0:mapped[@id='key']/n0:indexed[position() = 2]/@attribute

When providing a XSD document, the default configuration allows to transpose property values that are themselves complex elements, as defined in the XSD schema, into a new stream. This behavior can be controlled via the flag auto-fragment.

For example, consider the next statement:

insert into ObservationStream
select ID, Observation from SensorEvent

The Observation as a property of the SensorEvent gets itself inserted into a new stream by name ObservationStream. The ObservationStream thus consists of a string-typed ID property and a complex-typed property named Observation, as described in the schema.

A further statement can use this stream to query:

select Observation.Command, Observation.Tag[0].ID from ObservationStream

Before continuing the discussion, here is an alternative syntax using the wildcard-select, that is also useful:

insert into TagListStream
select ID as sensorId, Observation.* from SensorEvent

The new TagListStream has a string-typed ID and Command property as well as an array of Tag properties that are complex types themselves as defined in the schema.

Next is a sample statement to query the new stream:

select sensorId, Command, Tag[0].ID from TagListStream

Please note the following limitations:

EPL automatically registers a new event type for transposed properties. It generates the type name of the new XML event type from the XML event type name and the property names used in the expression. The synposis is type_name.property_name[.property_name...]. The type name can be looked up, for example for use with EventSender or can be created in advance.

Without a schema document a XML event may still be queried. However there are important differences in the metadata available without a schema document and therefore the property expression results. These differences are outlined below.

All property expressions against a XML type without schema are assumed valid. There is no validation of the property expression other than syntax validation. At runtime, property expressions return string-type values or null if the expression did not yield a matching element or attribute result.

When asked for property names or property metadata, a no-schema type returns empty array.

In all other aspects the type behaves the same as the schema-provided type described earlier.

Regardless of whether or not you provide a XSD schema for the XML event type, you can always fall back to configuring explicit properties that are backed by XPath expressions.

For further documentation on XPath, please consult the XPath standard or other online material. Consider using Jaxen or Apache Axiom, for example, to provide faster XPath evaluation then your Java VM built-in XPath provider may offer.

An explicit property may return XPathConstants.NODE or XPathConstants.NODESET and can provide the event type name of a pre-configured event type for the property. The method name to add such properties is addXPathPropertyFragment.

This code snippet adds two explicit properties and assigns an event type name for each property:

sensorcfg.addXPathPropertyFragment("tagOne", "//ss:Tag[position() = 1]", 
    XPathConstants.NODE, "TagEvent");
sensorcfg.addXPathPropertyFragment("tagArray", "//ss:Tag", 
    XPathConstants.NODESET, "TagEvent");

This EPL snippet is the equivalent of above for use with create xml schema:

@XMLSchemaField(name='tagOne', xpath='//ss:Tag[position() = 1]', type='node', eventTypeName='TagEvent')
@XMLSchemaField(name='tagArray', xpath='//ss:Tag', type='nodeset', eventTypeName='TagEvent')

The configuration or annotation above references the TagEvent event type. This type must also be configured or created. Prefix the root element name with "//" to cause the lookup to search the nested schema elements for the definition of the type:

ConfigurationCommonEventTypeXMLDOM tagcfg = new ConfigurationCommonEventTypeXMLDOM();
tagcfg.setRootElementName("//Tag");
tagcfg.setSchemaResource(schemaURL);

Configuration configuration = new Configuration();
configuration.getCommon().addEventType("TagEvent", tagcfg);

The tagOne and tagArray properties are now ready for selection and transposing to further streams:

insert into TagOneStream select tagOne.* from SensorEvent

Select from the new stream:

select ID from TagOneStream

An example with indexed properties is shown next:

insert into TagArrayStream select tagArray as mytags from SensorEvent

Select from the new stream:

select mytags[0].ID from TagArrayStream

Further information on using create xml schema with XMLSchema, XMLSchemaNamespacePrefix and XMLSchemaField can be found at Section 17.4.8, “Events Represented by org.w3c.dom.Node”.

Note

  • The create xml schema statement does not allow specifying event properties.

  • The create xml schema statement does not support copyfrom and inherits.