如果我有这样的 XML:
<foo>
<bar id="1" score="192" />
<bar id="2" score="227" />
<bar id="3" score="105" />
...
</foo>
我可以使用 XPath 找到 的最小值和最大值score
吗?
编辑:我正在使用的工具(Andariel ant 任务)不支持 XPath 2.0 解决方案。
这是一个稍微短一些的解决方案。
最大:
/foo/bar/@score[not(. < ../../bar/@score)][1]
最低限度:
/foo/bar/@score[not(. > ../../bar/@score)][1]
我已经编辑了谓词,使其适用于任何序列bar
,即使您决定更改路径。请注意,属性的父级是它所属的元素。
如果将这些查询嵌入 XSLT 或 ant 脚本等 XML 文件中,请记住编码<
并>
尊重.<
>
原来该工具不支持 XPath 2.0。
XPath 1.0 没有花哨min()
和max()
功能,所以要找到这些值,我们需要对 XPath 逻辑有点棘手,并比较节点的兄弟节点上的值:
最大:
/foo/bar[not(preceding-sibling::bar/@score >= @score)
and not(following-sibling::bar/@score > @score)]/@score
最低限度:
/foo/bar[not(preceding-sibling::bar/@score <= @score)
and not(following-sibling::bar/@score < @score)]/@score
如果将这些查询嵌入 XSLT 或 ant 脚本等 XML 文件中,请记住编码<
并>
尊重.<
>
我偶然发现了该线程并没有找到适合我的答案,所以我最终最终使用的答案在哪里......
输出最小值,当然您可以选择从具有最小值的节点输出@id 而不是您选择。
<xsl:for-each select="/foo">
<xsl:sort select="@score"/>
<xsl:if test="position()=1">
<xsl:value-of select="@score"/>
</xsl:if>
</xsl:for-each>
最大值相同:
<xsl:for-each select="/foo">
<xsl:sort select="@score" order="descending"/>
<xsl:if test="position()=1">
<xsl:value-of select="@score"/>
</xsl:if>
</xsl:for-each>
试试这个:
//foo/bar[not(preceding-sibling::bar/@score <= @score) and not(following-sibling::bar/@score <= @score)]
也许这将适用于 XPath 1.0。
我知道这是五岁。只需为可能搜索并遇到此问题的人添加更多选项。
与此类似的东西在 XSLT 2.0 中对我有用。
min(//bar[@score !='']/@score)
这!=''
是为了避免产生 NaN 值的空值(可能有更好的方法来做到这一点)
这是一个有效的 xpath/xquery:
//bar/@score[@score=min(//*[@score !='']/number(@score))]