31

如果我有这样的 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 解决方案。

4

6 回答 6

43

这是一个稍微短一些的解决方案。

最大:

/foo/bar/@score[not(. < ../../bar/@score)][1]

最低限度:

/foo/bar/@score[not(. > ../../bar/@score)][1]

我已经编辑了谓词,使其适用于任何序列bar,即使您决定更改路径。请注意,属性的父级是它所属的元素。

如果将这些查询嵌入 XSLT 或 ant 脚本等 XML 文件中,请记住编码<>尊重.&lt;&gt;

于 2009-07-15T07:32:44.493 回答
19

原来该工具不支持 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 文件中,请记住编码<>尊重.&lt;&gt;

于 2009-07-15T07:01:28.347 回答
6

这应该工作......

max(foo/bar/@score)

... 和 ...

min(foo/bar/@score)

...查看此功能参考

于 2009-07-15T00:20:06.313 回答
5

我偶然发现了该线程并没有找到适合我的答案,所以我最终最终使用的答案在哪里......

输出最小值,当然您可以选择从具有最小值的节点输出@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>
于 2012-05-30T18:06:11.093 回答
3

试试这个:

//foo/bar[not(preceding-sibling::bar/@score <= @score) and not(following-sibling::bar/@score <= @score)]

也许这将适用于 XPath 1.0。

于 2009-07-15T00:32:07.223 回答
3

我知道这是五岁。只需为可能搜索并遇到此问题的人添加更多选项。

与此类似的东西在 XSLT 2.0 中对我有用。

min(//bar[@score !='']/@score)

!=''是为了避免产生 NaN 值的空值(可能有更好的方法来做到这一点)

这是一个有效的 xpath/xquery:

//bar/@score[@score=min(//*[@score !='']/number(@score))]
于 2013-11-18T17:42:25.913 回答