如果我有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解决方案。
答案 0 :(得分:39)
这是一个稍短的解决方案。
最大:
/foo/bar/@score[not(. < ../../bar/@score)][1]
最小
/foo/bar/@score[not(. > ../../bar/@score)][1]
我编辑了谓词,以便它适用于bar
的任何序列,即使您决定更改路径。请注意,attribute的parent是它所属的元素。
如果将这些查询嵌入XSLT或ant脚本等XML文件中,请记住将<
和>
编码为尊重<
的{{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文件中,请记住将<
和>
编码为尊重<
的{{1}}。
答案 2 :(得分:6)
答案 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))]