如何使用XPath在一组元素中查找属性的最小值?

时间:2009-07-15 00:11:05

标签: xml xpath xpath-1.0

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

6 个答案:

答案 0 :(得分:39)

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

最大:

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

最小

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

我编辑了谓词,以便它适用于bar的任何序列,即使您决定更改路径。请注意,attribute的parent是它所属的元素。

如果将这些查询嵌入XSLT或ant脚本等XML文件中,请记住将<>编码为尊重&lt;的{​​{1}}。

答案 1 :(得分: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;的{​​{1}}。

答案 2 :(得分:6)

这应该有用......

max(foo/bar/@score)

......和......

min(foo/bar/@score)

...查看此function reference

答案 3 :(得分:4)

我偶然发现了这个帖子并没有找到对我有用的答案,所以最终我最终使用的是哪个......

输出最低值,当然您可以选择从具有最低值的节点输出@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>

答案 4 :(得分:3)

试试这个:

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

也许这适用于XPath 1.0。

答案 5 :(得分:3)

我知道这已经五岁了。只需为可能搜索的人添加更多选项,然后再进行搜索。

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

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

!=''是为了避免产生NaN值的空值(可能有更好的方法)

这是一个有效的xpath / xquery:

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