Подтвердить что ты не робот

Как я могу использовать XPath для поиска минимального значения атрибута в наборе элементов?

Если у меня есть 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.

4b9b3361

Ответ 1

Оказывается, инструмент не поддерживает XPath 2.0.

XPath 1.0 не имеет функций min() и max(), поэтому, чтобы найти эти значения, нам нужно немного сложнее с логикой XPath и сравнить значения для братьев и сестер node:

Максимум:

/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

Если вы вставляете эти запросы в файлы XML, такие как скрипты XSLT или ant, не забудьте закодировать < и > как &lt; соблюдая &gt;.

Ответ 2

Здесь немного более короткое решение.

Максимум:

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

Минимум:

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

Я отредактировал предикат так, чтобы он применим к любой последовательности bar, даже если вы решили изменить путь. Обратите внимание, что родительский атрибут - это элемент, к которому он принадлежит.

Если вы вставляете эти запросы в файлы XML, такие как скрипты XSLT или ant, не забудьте закодировать < и > как &lt; в отношении &gt;.

Ответ 3

Это должно работать...

max(foo/bar/@score)

... и...

min(foo/bar/@score)

... проверьте эту ссылку .

Ответ 4

Я наткнулся на нить и не нашел ответа, который сработал у меня, поэтому где же я в конечном итоге использовал...

Выводит самое низкое значение, конечно, вы можете выбрать вывод @id из node с наименьшим значением, а не выбором.

<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>

Ответ 5

Попробуйте следующее:

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

Возможно, это будет работать на XPath 1.0.

Ответ 6

Я знаю, что это пять лет. Просто добавьте еще несколько опций для тех, кто может найти и найти это.

Нечто похожее на это сработало для меня в XSLT 2.0.

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

!='' должен был избегать нулей, которые приводили значения NaN (возможно, лучший способ сделать это)

Вот рабочий xpath/xquery:

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