Как вы идентифицируете повторяющиеся значения в числовой последовательности, используя XPath 2.0? - PullRequest
12 голосов
/ 25 сентября 2008

У меня есть выражение XPath, которое предоставляет мне последовательность значений, подобную приведенной ниже:

1 2 2 3 4 5 5 6 7

Легко преобразовать это в набор уникальных значений 1 2 3 4 5 6 7, используя distinct-values(). Тем не менее, я хочу извлечь список повторяющихся значений = 2 5. Я не могу придумать простой способ сделать это. Кто-нибудь может помочь?

Ответы [ 4 ]

17 голосов
/ 13 ноября 2008

Используйте это простое выражение XPath 2.0 :

$vSeq[index-of($vSeq,.)[2]]

где $vSeq - последовательность значений, в которой мы хотим найти дубликаты.

Для объяснения того, как это "работает", см. :

http://dnovatchev.wordpress.com/2008/11/16/xpath-2-0-gems-find-all-duplicate-values-in-a-sequence-part-2/

TLDR; Эта картина может быть наглядным объяснением.

Если последовательность:

$vSeq  =  1,   2,   3,   2,   4,   5,   6,   7,   5,   7,   5

Затем вычисление приведенного выше выражения XPath дает: 2, 5, 7


enter image description here

3 голосов
/ 25 сентября 2008

А как же:

distinct-values(
  for $item in $seq
  return if (count($seq[. eq $item]) > 1)
         then $item
         else ())

Это перебирает элементы в последовательности и возвращает элемент, если количество элементов в последовательности, равных этому элементу, больше единицы. Затем вы должны использовать distinct-values(), чтобы удалить дубликаты из этого списка.

1 голос
/ 25 сентября 2008

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

0 голосов
/ 29 сентября 2008

А как насчет xsl? Это применимо к вашему запросу?

    <xsl:for-each select="/r/a">
        <xsl:variable name="cur" select="." />
        <xsl:if test="count(./preceding-sibling::a[. = $cur]) > 0 and count(./following-sibling::a[. = $cur]) = 0">
            <xsl:value-of select="." />
        </xsl:if>
    </xsl:for-each>
...