繁体   English   中英

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

[英]How to get the real Node order from xpath expression (java)

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

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

如果我尝试评估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实现此目的:

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

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

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

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

/library/book[position() < 3]

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM