如果我有一个使用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
,我会收到此订单:
但如果我尝试评估:/library/book[3]/preceding-sibling::book[1]
,我会得到Node
:
那么,我怎样才能从这种表达式中获得真正的顺序:
/library/book[3]/preceding-sibling::book
?
答案 0 :(得分:5)
来自http://www.w3.org/TR/xpath/#predicates
轴是前轴或 反转轴。一个永远的轴 包含上下文节点或节点 在上下文节点之后 文档顺序是前进轴。一个 只包含的轴 上下文节点或之前的节点 文档顺序中的上下文节点是 反转轴。因此,祖先, 祖先或自我,先于,和 前兄弟轴是反向的 轴;所有其他轴都是前轴。 由于自身轴始终包含at 大多数节点,它没有任何区别 无论是前进还是后退 轴。 a的接近位置 相对于节点集的成员 轴被定义为位置 在...中排序的节点集中的节点 如果轴是a,则为文档顺序 前进轴和反向排序 如果轴是a,则为文档顺序 反转轴。第一个位置是1.
关于使用特定XPath引擎评估某些XPath表达式后结果节点集的顺序,这完全取决于实现。在XSLT中,当指令处理按文档顺序排序的节点集时,会明确定义它。在XPath中,这是在http://www.w3.org/TR/xpath/#section-Introduction中定义节点集的方式:
node-set(无序集合 没有重复的节点)
答案 1 :(得分:3)
节点集没有顺序(根据定义,集合是无序的)。大多数XPath API通过在文档顺序中评估XPath表达式来呈现节点集结果,这是您在问题中观察和报告的内容。
XPath是一种查询(只读)语言,因此它永远不会修改源XML文档的结构 - 所选节点的节点集中的节点与源XML文档中的结构相同。除其他外,结构包括 order 。
如果您需要在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>
答案 2 :(得分:2)
preceding-sibling
轴按相反顺序编制索引。 preceding-sibling::*[1]
是先前的兄弟节点,即上下文节点之前的兄弟节点。
显然,Java按文档顺序返回NodeList
。有关节点集顺序(及其在宿主语言中的表示)的更多详细信息,请参阅@ Alejandro的答案。
因此,从另一端迭代NodeList
将是一种选择。也试试这个XPath。
/library/book[position() < 3]
结果将再次按文档顺序排列,但表达式不如您的复杂。