XPath 2.0: поиск количества различных элементов перед первым элементом с текущим значением узла

Установка: я использую XPath 2.0. Но внутри Altova Stylevision см. мой комментарий позже.

У меня есть следующая структура XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <entries>
        <bla>
            <blub>222</blub>
        </bla>
        <bla>
            <blub>222</blub>
        </bla>
        <bla>
            <blub>123</blub>
        </bla>
        <bla>
            <blub>234</blub>
        </bla>
        <bla>
            <blub>123</blub>
            <!--I want to find the number of distinct elements before the first occurance of a blub element with the same value as the current node - so for this node the result should be one (two times 222 before the first appearance of 123)-->
        </bla>
    </entries>

При анализе этого файла я хотел бы знать при каждом появлении blub: сколько различных значений blub существует до первого появления blub с тем же значением, что и текущий узел.

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

Одна из моих проблем заключается в том, что Altova не поддерживает функцию current(). Цитата: «Обратите внимание, что функция current() является функцией XSLT, а не функцией XPath, и поэтому ее нельзя использовать в автоматических вычислениях и условных шаблонах StyleVision. Чтобы выбрать текущий узел в выражении, используйте выражение for XPath 2.0. "

Так что любое решение, которое могло бы обойтись без функции current(), было бы отличным;)

Спасибо всем!

Стево


person spse    schedule 20.07.2012    source источник
comment
В качестве небольшого комментария мне удалось получить count(distinct-values(../preceding-sibling::bla/blub)) но это явно не начинается с первого узла с тем же значением, что и текущий, но вместо этого он начинается с текущего узла. Решил выложить, вдруг поможет...   -  person spse    schedule 20.07.2012


Ответы (1)


Если вам нужен первый узел с таким же значением, вы всегда можете начать с самого начала и искать его с помощью /entries/bla[blub=string()][1]. (строка без параметра должна возвращать значение текущего узла)

И тогда вы можете вставить его в свое выражение и получить

count(distinct-values( /entries/bla[blub=string()][1]/preceding-sibling::bla/blub ))

И если вам это нужно для всех блабов, вы можете посчитать это для всех:

for $x in /entries/bla/blub return count(distinct-values( /entries/bla[blub=string($x)][1]/preceding-sibling::bla/blub ))

edit: однако это может быть медленным, так много циклов. Если отдельные значения в этом Stylevision сохраняют порядок элементов, количество элементов перед значением является индексом этого значения в последовательности уникальных значений.

Таким образом, вы можете подсчитать один узел с помощью index-of(distinct-values(/entries/bla/blub), string()) - 1 и подсчитать все узлы с помощью

for $x in /entries/bla/blub return index-of(distinct-values(/entries/bla/blub), $x) - 1

И если возможно определить новые переменные, вы можете установить $s в distinct-values(/entries/bla/blub) и упростить его до

for $x in /entries/bla/blub return index-of($s, $x) - 1
person BeniBela    schedule 20.07.2012
comment
Спасибо за ваши ответы! Altova, похоже, не поддерживает функцию string() при использовании вашего предложения: index-of(distinct-values(/entries/bla/blub), string()) - 1 бит string() не возвращает текущее значение узла. Но: для $x в . return index-of(distinct-values(/entries/bla/blub), $x) - 1 делает свое дело, поэтому кажется, что обходной путь существует. - person spse; 20.07.2012