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

发布于 2024-07-26 22:34:24 字数 368 浏览 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 解决方案。

If I have XML like:

<foo>
  <bar id="1" score="192" />
  <bar id="2" score="227" />
  <bar id="3" score="105" />
  ...
</foo>

Can I use XPath to find the minimum and maximum values of score?

Edit: The tool i'm using (Andariel ant tasks) doesn't support the XPath 2.0 solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

剩余の解释 2024-08-02 22:34:24

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

最大值:

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

最小值:

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

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

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

Here's a slightly shorter solution.

Maximum:

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

Minimum:

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

I've edited the predicate so that it's applicable to any sequence of bar, even if you decide to change the path. Note that parent of attribute is the element to which it belongs.

If embedding these queries in XML files like XSLT or ant scripts, remember to encode < and > as < respecting >.

小梨窩很甜 2024-08-02 22:34:24

结果发现该工具不支持 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 文件中,请记住对 <> 作为 < 尊重 >

Turns out the tool does not support XPath 2.0.

XPath 1.0 doesn't have the fancy min() and max() functions, so to find these values we need to be a little tricky with the XPath logic, and compare the values on the siblings of the node:

Maximum:

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

Minimum:

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

If embedding these queries in XML files like XSLT or ant scripts, remember to encode < and > as < respecting >.

好菇凉咱不稀罕他 2024-08-02 22:34:24

这应该有效......

max(foo/bar/@score)

并且

min(foo/bar/@score)

......查看这个函数参考。

This should work ...

max(foo/bar/@score)

... and ...

min(foo/bar/@score)

... check out this function reference.

幸福%小乖 2024-08-02 22:34:24

我偶然发现了这个线程,但没有找到适合我的答案,所以我最终使用的是什么...

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

I stumbled upon the thread and didn't find an answer that worked for me, so where is what I eventually ended up using...

Outputs the lowest value, of course you could choose to output the @id from the node with the lowest value instead of you choose.

<xsl:for-each select="/foo">
  <xsl:sort select="@score"/>
  <xsl:if test="position()=1">
    <xsl:value-of select="@score"/>
  </xsl:if>
</xsl:for-each>

The same for the maximum value:

<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>
星星的轨迹 2024-08-02 22:34:24

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

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

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

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

这是一个有效的 xpath/xquery:

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

I know this is five years old. Just adding some more options for whoever may search and come across this.

Something similar to this worked for me in XSLT 2.0.

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

The !='' was to avoid a nulls which brought up NaN values (there's probably a better way to do that)

Here is a working xpath/xquery:

//bar/@score[@score=min(//*[@score !='']/number(@score))]
风流物 2024-08-02 22:34:24

试试这个:

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

也许这适用于 XPath 1.0。

Try this:

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

Maybe this will work on XPath 1.0.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文