私のような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ソリューションをサポートしていません。
ツールが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ファイルに埋め込む場合は、<
および>
なので <
尊重>
。
これが少し短い解決策です。
最大:
/foo/bar/@score[not(. < ../../bar/@score)][1]
最小:
/foo/bar/@score[not(. > ../../bar/@score)][1]
パスを変更する場合でも、bar
の任意のシーケンスに適用できるように述語を編集しました。属性の親は、それが属する要素であることに注意してください。
これらのクエリをXSLTやantスクリプトなどのXMLファイルに埋め込む場合は、<
および>
なので <
尊重>
。
スレッドを見つけたのですが、うまくいく答えが見つかりませんでした。
最低値を出力します。もちろん、選択する代わりに、最低値を持つノードから@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>
これを試して:
//foo/bar[not(preceding-sibling::bar/@score <= @score) and not(following-sibling::bar/@score <= @score)]
多分これはXPath 1.0で動作するでしょう。
これは5歳です。検索してこれに遭遇する可能性がある人のために、いくつかのオプションを追加するだけです。
XSLT 2.0では、これに似たものがうまくいきました。
min(//bar[@score !='']/@score)
!=''
は、NaN値を引き起こすnullを回避するためのものでした(おそらく、これを行うためのより良い方法があります)。
以下は、動作するxpath/xqueryです。
//bar/@score[@score=min(//*[@score !='']/number(@score))]