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

如何从xpath表达式(java)获取实际节点顺序,java,xslt,xpath,Java,Xslt,Xpath,如果有一个XPath表达式使用了前面的同级::,则会得到顺序不正确的节点列表。我怎样才能得到正确的订单?例如: <library> <book name="book1"> hello </book> <book name="book2"> world </book> <book name="book3"> !!! </book> </library>

如果有一个XPath表达式使用了前面的同级::,则会得到顺序不正确的
节点列表。我怎样才能得到正确的订单?例如:

<library>
  <book name="book1">
    hello
  </book>
  <book name="book2">
    world
  </book>
  <book name="book3">
    !!!
  </book>
</library>

你好
世界
!!!
如果我尝试计算XPath表达式:
/library/book[3]/previous sibling::book
,则得到以下顺序:

  • 第一册
  • 第二册
但是如果我尝试计算:
/library/book[3]/previous sibling::book[1]
,我会得到
节点

  • 第二册
那么,我如何从这种表达式中得到真正的顺序:


/library/book[3]/previous sibling::book

前面的sibling
轴按相反顺序索引<代码>前面的同级::*[1]是前面的第一个同级,即上下文节点前面的同级

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

因此,可以选择从另一端迭代
节点列表。也可以试试这个XPath

/library/book[position() < 3]
/library/book[position()<3]
结果将再次按文档顺序排列,但表达式没有您的表达式复杂。

From

轴可以是前进轴,也可以是前进轴 反转轴。一个只有永远的轴心 包含上下文节点 在中的上下文节点之后 文档顺序是一个前进轴。一 仅包含 上下文节点或之前的节点 文档顺序中的上下文节点为 反向轴。因此,祖先, 祖先或自我,先于,和 前面的同级轴是相反的 轴线;所有其他轴均为正向轴。 因为自轴始终包含在 大多数情况下,只有一个节点没有区别 无论是正向还是反向 轴a的接近位置 关于的节点集的成员 轴被定义为位置 在中排序的节点集中的节点的 文档顺序(如果轴是 正向和反向排列的轴 文档顺序(如果轴是 反转轴。第一个位置是1

关于使用特定XPath引擎计算某些XPath表达式后结果节点集的顺序,这完全取决于实现。在XSLT中,当指令处理按文档顺序排序的节点集时,它是显式定义的。在XPath中,节点集是如何在中定义的:

节点集(一个无序的 节点(无重复项)


这就是为什么在标准domapi中需要获得有序和无序的结果,而在

中,节点集没有顺序(根据定义,集是无序的)。大多数XPathAPI提供了按文档顺序计算XPath表达式的节点集结果,这是您在问题中观察和报告的结果

XPath是一种查询(只读)语言,因此它从不修改源XML文档的结构——所选节点集中的节点与其在源XML文档中的结构相同。结构,除其他外,包括秩序

如果需要以XML文档中的原始顺序以外的其他顺序返回节点,则仅使用XPath无法完成此操作

可以使用XSLT实现这一目的:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="library">
  <xsl:apply-templates select="*[not(position() >2)]">
   <xsl:sort select="position()"
   data-type="number" order="descending"/>
  </xsl:apply-templates>
 </xsl:template>
</xsl:stylesheet>

在提供的XML文档上应用此转换时:

<library>
    <book name="book1">     hello   </book>
    <book name="book2">     world   </book>
    <book name="book3">     !!!   </book>
</library>
<book name="book2">     world   </book>
<book name="book1">     hello   </book>

你好
世界
!!!   
生成所需的正确结果:

<library>
    <book name="book1">     hello   </book>
    <book name="book2">     world   </book>
    <book name="book3">     !!!   </book>
</library>
<book name="book2">     world   </book>
<book name="book1">     hello   </book>
世界
你好

so/library/book[position()<3和position()>1]将选择上一个元素?有没有更简洁的表达方式?@Liviu
/library/book[position()<3和position()>1]
相当于
/library/book[position()=2]
相当于
/library/book[2]
。你所说的“先前元素”是什么意思?在什么之前?在
/library/book[3]
之前……我想我没有正确理解这个问题:)你写的“这种行为[有序结果]是标准化的”不太正确。用正确的链接检查我的答案。@Alejandro:显然,对于Java来说,这是文档顺序,但你是对的,这是一个实现细节,没有什么可依赖的。我将删除该语句。如果我使用这样的代码:(清单4)如何根据第一个问题中的路径以正确的顺序获取节点列表或任何其他类型的列表?@fonet:该实现包装器不会区分有序和无序的节点集。好问题,+1。请参阅我的答案,以获得解释和完整、简短且简单的XSLT解决方案。:)