如何从xpath表达式获取实际的Node顺序(java)

如果我有一个使用preceding-sibling::的XPath表达式,我得到的NodeList不是正确的顺序。 我怎样才能得到正确的订单? 例:

   hello   world   !!!   

如果我尝试评估XPath表达式: /library/book[3]/preceding-sibling::book ,我得到这个顺序:

  • BOOK1
  • 第二册

但是,如果我尝试评估: /library/book[3]/preceding-sibling::book[1] ,我得到Node

  • 第二册

那么,我怎样才能从这种表达式中获得真正的顺序:

/library/book[3]/preceding-sibling::book

来自http://www.w3.org/TR/xpath/#predicates

轴是前轴或倒轴。 仅包含上下文节点或文档顺序中的上下文节点之后的节点的轴是前向轴。 仅包含文档顺序中上下文节点之前的上下文节点的轴是反向轴。 因此,祖先,祖先或自我,先前和前兄弟轴是反向轴; 所有其他轴都是前轴。 由于自轴总是包含至多一个节点,因此它是正向轴还是反向轴没有区别。 节点集的成员相对于轴的接近位置被定义为如果轴是前向轴并且按照相反的文档顺序排序,则按文档顺序排序的节点集中的节点的位置。是一个反向轴。 第一个位置是1。

关于使用特定XPath引擎评估某些XPath表达式后结果节点集的顺序,这完全取决于实现。 在XSLT中,当指令处理按文档顺序排序的节点集时,会明确定义它。 在XPath中,这是在http://www.w3.org/TR/xpath/#section-Introduction中定义节点集的方式:

node-set(没有重复的无序节点集合)

这就是为什么在标准DOM API中有一些设置可以获得有序和无序的结果以及XQuery

节点集没有顺序(根据定义,集合是无序的)。 大多数XPath API通过按文档顺序评估XPath表达式来显示节点集结果,这是您在问题中观察和报告的内容。

XPath是一种查询(只读)语言,因此它永远不会修改源XML文档的结构 – 所选节点的节点集中的节点与源XML文档中的结构相同。 除其他外,结构包括订单

如果您需要以与XML文档中的原始顺序不同的顺序返回的节点,单独使用XPath无法完成此操作

可以使用XSLT来实现此目的:

               

当此转换应用于提供的XML文档时:

   hello   world   !!!   

产生了想要的正确结果:

  world   hello  

preceding-sibling轴以相反的顺序索引。 preceding-sibling::*[1]是前面的第一个兄弟节点,即在上下文节点之前的节点。

显然,Java按文档顺序返回NodeList 。 有关节点集顺序(及其在宿主语言中的表示)的更多详细信息,请参阅@ Alejandro的答案。

因此,从另一端迭代NodeList将是一种选择。 也试试这个XPath。

 /library/book[position() < 3] 

结果将再次按文档顺序排列,但表达式不如您的复杂。