XPath 2.0: Finding number of distinct elements before first element with current node's value

StackOverflow https://stackoverflow.com/questions/11576994

  •  22-06-2021
  •  | 
  •  

Question

Setup: I am using XPath 2.0. But inside Altova Stylevision, see my comment later on.

I have got the following XML structure:

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

When parsing that I file I would like to know at each occurance of a blub: How many distinct values of blub's are there before the first occurance of a blub with the same value as the current node.

So basically first determining where the first occurance of a blub with the same value as the current node is, and then figuring out the number of distinct blubs before.

One of my problems is that Altova doesn't support the current() function. Quote: "Note that the current() function is an XSLT function, not an XPath function, and cannot therefore be used in StyleVision's Auto-Calculations and Conditional Templates. To select the current node in an expression use the for expression of XPath 2.0."

So any solution that could do without the current() function would be great ;)

Thanks all!

Stevo

Was it helpful?

Solution

If you need the first node with the same value, you can always start at the beginning and search it with /entries/bla[blub=string()][1]. (string without parameter should return the value of the current node)

And then you can insert it in your expression and get

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

And if you need it for all blubs you can count it for all of them:

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

edit: it might however be slow to perform, so many loops. If distinct-values in that Stylevision preserves the order of the elements, the number of elements before a value is the index of that a value in the distinct value sequence.

So you can the count for one node with index-of(distinct-values(/entries/bla/blub), string()) - 1 and the count for all nodes with

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

And if it is possible to define new variables you could set $s to distinct-values(/entries/bla/blub) and simplify it to

for $x in /entries/bla/blub return index-of($s, $x) - 1
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top