Vraag Hoe kan ik XPath gebruiken om de minimumwaarde van een kenmerk in een reeks elementen te vinden?


Als ik XML heb zoals:

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

Kan ik XPath gebruiken om de minimum- en maximumwaarden van te vinden score?

Bewerk: De tool die ik gebruik (Andariel ant taken) ondersteunt de XPath 2.0-oplossing niet.


28
2017-07-15 00:11


oorsprong


antwoorden:


Hier is een iets kortere oplossing.

maximaal:

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

Minimum:

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

Ik heb het predicaat bewerkt, zodat het van toepassing is op elke reeks van bar, zelfs als u besluit het pad te wijzigen. Merk op dat ouder van attribuut het element is waartoe het behoort.

Als u deze query's insluit in XML-bestanden zoals XSLT of mier-scripts, vergeet dan niet te coderen < en > als &lt; met inachtneming van &gt;.


38
2017-07-15 07:32



Blijkt dat de tool geen ondersteuning biedt voor XPath 2.0.

XPath 1.0 heeft niet de voorkeur min() en max() functies, dus om deze waarden te vinden moeten we een beetje lastig zijn met de XPath-logica en de waarden op de broers en zussen van het knooppunt vergelijken:

maximaal:

/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

Als u deze query's insluit in XML-bestanden zoals XSLT of mier-scripts, vergeet dan niet te coderen < en > als &lt; met inachtneming van &gt;.


18
2017-07-15 07:01



Dit zou moeten werken ...

max(foo/bar/@score)

... en ...

min(foo/bar/@score)

... kijk hier eens naar functie referentie.


6
2017-07-15 00:20



Ik struikelde over de draad en vond geen antwoord dat werkte voor mij, dus waar is wat ik uiteindelijk uiteindelijk gebruikte ...

Voert de laagste waarde uit, u kunt er natuurlijk voor kiezen om de @id uit te voeren vanaf het knooppunt met de laagste waarde in plaats van u kiest.

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

Hetzelfde voor de maximale waarde:

<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
2018-05-30 18:06



Probeer dit:

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

Misschien werkt dit op XPath 1.0.


3
2017-07-15 00:32



Ik weet dat dit vijf jaar oud is. Gewoon wat meer opties toevoegen voor iedereen die kan zoeken en dit tegenkomt.

Iets soortgelijks als dit werkte voor mij in XSLT 2.0.

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

De !='' was om nulls te vermijden die NaN-waarden naar voren brachten (er is waarschijnlijk een betere manier om dat te doen)

Hier is een werkende xpath / xquery:

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

3
2017-11-18 17:42