web-dev-qa-db-ja.com

XPathを使用して、要素のセット内の属性の最小値を見つけるにはどうすればよいですか?

私のようなXMLがある場合:

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

XPathを使用してscoreの最小値と最大値を見つけることはできますか?

Edit:( Andariel ant tasks)を使用しているツールは、XPath 2.0ソリューションをサポートしていません。

29
brasskazoo

ツールが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;

19
brasskazoo

これが少し短い解決策です。

最大:

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

最小:

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

パスを変更する場合でも、barの任意のシーケンスに適用できるように述語を編集しました。属性の親は、それが属する要素であることに注意してください。

これらのクエリをXSLTやantスクリプトなどのXMLファイルに埋め込む場合は、<および> なので &lt;尊重&gt;

39
Pavel Minaev

これはうまくいくはずです...

max(foo/bar/@score)

...と...

min(foo/bar/@score)

...これをチェックしてください 関数リファレンス

6
JP Alioto

スレッドを見つけたのですが、うまくいく答えが見つかりませんでした。

最低値を出力します。もちろん、選択する代わりに、最低値を持つノードから@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
Graham Lower

これを試して:

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

多分これはXPath 1.0で動作するでしょう。

3
kuy

これは5歳です。検索してこれに遭遇する可能性がある人のために、いくつかのオプションを追加するだけです。

XSLT 2.0では、これに似たものがうまくいきました。

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

!=''は、NaN値を引き起こすnullを回避するためのものでした(おそらく、これを行うためのより良い方法があります)。

以下は、動作するxpath/xqueryです。

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