Pregunta

Can I depend on the order of the messages output from an int-xml:xpath-splitter?

I am using:

  • Java 1.6
  • spring-integration-xml-3.0.0.RELEASE
  • spring-xml-2.1.1.RELEASE
  • Saxon-HE-9.4.0-9

Example:

Given the following XML Document:

<?xml version="1.0" encoding="UTF-8"?>
<tests>
    <test>test</test>
    <test>test2</test>
</tests>

And the following int-xml:xpath-splitter:

<int-xml:xpath-splitter id="messageSplitter" 
input-channel="inbound"
    output-channel="routing"
    create-documents="false">

    <int-xml:xpath-expression expression="/*/*"/>
</int-xml:xpath-splitter>

<int:channel id="routing">
    <int:queue/>
</int:channel>

Will the routing channel always receive <test>test</test> before <test>test2</test>?

¿Fue útil?

Solución

I believe the answer to this question is it depends on which JAXP provider you are using.

If you have configured an XPath engine that supports XPath 2.0; then yes, messages will be in document-order.

If you use the default or an XPath 1.0 engine; then no, order cannot be guaranteed1.


Does XPath support ordering?

XPath 1.0 does not1, XPath 2.0 does.

According to the XPath 1.0 specification, XPath 1.0 expressions return node-set types and node-set types are unordered:

The primary syntactic construct in XPath is the expression. An expression matches the production Expr. An expression is evaluated to yield an object, which has one of the following four basic types:

  • node-set (an unordered collection of nodes without duplicates)
  • boolean (true or false)
  • number (a floating-point number)
  • string (a sequence of UCS characters)

On the other hand, the XPath 2.0 specification introduces the idea of document order:

Document order is a total ordering, although the relative order of some nodes is implementation-dependent. [Definition: Informally, document order is the order in which nodes appear in the XML serialization of a document.] [Definition: Document order is stable, which means that the relative order of two nodes will not change during the processing of a given expression, even if this order is implementation-dependent.]

The specification also states that evaluation of Path Expressions returns a sequence of nodes in document order:

The sequences resulting from all the evaluations of E2 are combined as follows:

If every evaluation of E2 returns a (possibly empty) sequence of nodes, these sequences are combined, and duplicate nodes are eliminated based on node identity. The resulting node sequence is returned in document order. If every evaluation of E2 returns a (possibly empty) sequence of atomic values, these sequences are concatenated, in order, and returned. If the multiple evaluations of E2 return at least one node and at least one atomic value, a type error is raised [err:XPTY0018].

Does Spring Integration/Spring XML use XPath 1.0 or XPath 2.0?

Spring uses javax.xml.xpath.XPathFactory.newInstance(String uri) to create an XPathFactory that is used to create XPath objects. The JavaDoc explains in detail how XPathFactory.newInstance(uri) behaves, but suffice it to say that it searches for an appropriate factory within your project.

If your project does not specify differently, Spring will use a JAXP 1.3 implementation to create XPath Expressions.

As of Java 1.6, JAXP 1.3 only supports XPath 1.0.

What if I have an XPathFactory that supports XPath 2.0?

Refer to the documentation for the XPathFactory you are using.

In my case, I have Saxon-HE-9.4.0-9 setup for my project. Saxon implements the JAXP 1.3 API and Supports XPath 2.0.

The Saxon documentation for how XPath's are evaluated does not explicitly state that NODESET expressions will be returned in document-order. However, it does state that the return object is a Java List object.

Based on the fact that XPath 2.0 expressions return nodes in document-order, Saxon supports XPath 2.0, and Saxon returns a Java List object (which is ordered), I think that Saxon will return nodes in document-order.

So my factory returns nodes from my XPath expression in document-order; are the messages from xpath-splitter also in document-order?

Yes they will; based on my analysis of the code in org.springframework.integration.xml.splitter.XPathMessageSplitter.splitMessage(Message<?>).

Both splitDocument(document) and splitNode(Node node) retain the order of the List returned from the evaluation of the XPath Expression.


1. As noted by Michael Kay in his comment and answer on another question, although the XPath specification does not guarantee order, in practice implementations of XPath 1.0 generally also support XSLT 1.0 and will return nodes in document-order because XSLT requires it.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top