来自xpath-splitter的消息是否有序?

时间:2014-05-01 19:54:57

标签: java xpath spring-integration saxon

我可以依赖int-xml:xpath-splitter输出的消息的顺序吗?

我正在使用:

  • Java 1.6
  • 弹簧整合-XML的3.0.0.RELEASE
  • 弹簧XML的2.1.1.RELEASE
  • 撒克逊-HE-9.4.0-9

示例:

给出以下XML文档:

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

以下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>

routing渠道始终会在<test>test</test>之前收到<test>test2</test>吗?

1 个答案:

答案 0 :(得分:2)

我相信这个问题的答案取决于您使用的是哪个JAXP提供商。

如果您已配置支持XPath 2.0的XPath引擎;然后是的,消息将按文档顺序排列。

如果使用默认或XPath 1.0引擎;然后不,订单不能保证 1


XPath是否支持订购?

XPath 1.0不是 1 ,XPath 2.0。

根据XPath 1.0规范,XPath 1.0表达式返回node-set个类型,node-set类型是无序的:

  

XPath中的主要句法结构是表达式。表达式与生产Expr匹配。计算表达式以生成一个对象,该对象具有以下四种基本类型之一:

     
      
  • node-set(没有重复的无序节点集合)
  •   
  • 布尔值(true或false)
  •   
  • 数字(浮点数)
  •   
  • string(一系列UCS字符)
  •   

另一方面,XPath 2.0规范引入了document order

的概念
  

文档顺序是总排序,尽管某些节点的相对顺序依赖于实现。 [定义:非正式地,文档顺序是节点在文档的XML序列化中出现的顺序。] [定义:文档顺序是稳定的,这意味着在处理给定表达式期间两个节点的相对顺序不会改变,即使这个顺序依赖于实现。]

规范还指出,Path Expressions的评估按文档顺序返回节点序列:

  

E2的所有评估得到的序列如下组合:

     

如果E2的每个评估返回(可能是空的)节点序列,则组合这些序列,并且基于节点标识消除重复节点。生成的节点序列按文档顺序返回。   如果E2的每个评估返回一个(可能是空的)原子值序列,则按顺序连接这些序列并返回。   如果E2的多次评估返回至少一个节点和至少一个原子值,则会引发类型错误[错误:XPTY0018]。

Spring Integration / Spring XML是否使用XPath 1.0或XPath 2.0?

Spring使用javax.xml.xpath.XPathFactory.newInstance(String uri)创建一个用于创建XPath个对象的XPathFactory。 JavaDoc详细解释了XPathFactory.newInstance(uri)的行为方式,但足以说它在项目中搜索适当的工厂。

如果您的项目没有以不同的方式指定,Spring将使用JAXP 1.3实现来创建XPath表达式。

从Java 1.6开始,JAXP 1.3 only supports XPath 1.0

如果我有一个支持XPath 2.0的XPathFactory怎么办?

请参阅您正在使用的XPathFactory的文档。

就我而言,我的项目设置了Saxon-HE-9.4.0-9。撒克逊人implements the JAXP 1.3 API and Supports XPath 2.0

how XPath's are evaluated的Saxon文档未明确声明NODESET表达式将按文档顺序返回。但是,它确实声明返回对象是Java List对象。

基于XPath 2.0表达式按文档顺序返回节点的事实,Saxon支持XPath 2.0,Saxon返回一个Java List对象(有序),我认为Saxon将按文档顺序返回节点。

所以我的工厂以文档顺序从我的XPath表达式返回节点;来自xpath-splitter的邮件也是文档顺序吗?

是的,他们会;基于org.springframework.integration.xml.splitter.XPathMessageSplitter.splitMessage(Message<?>)中代码的我的分析

splitDocument(document)splitNode(Node node)都保留了从评估XPath表达式返回的List的顺序。


<子> 1。正如Michael Kay在他的评论和answer on another question中所指出的,虽然XPath 规范不保证顺序,但实际上XPath 1.0的实现通常也支持XSLT 1.0并且将返回节点文档顺序,因为XSLT需要它。