javarosa
javarosa copied to clipboard
Validate reports invalid self-reference for indexed-repeat()
Software versions
javaRosa as it exists in Validate as it exists in XSLForm Online v1.3.1
Problem description
using indexed-repeat() inside a repeat group to accumulate results, by referencing 'previous' repeat results; eg
if(position(..)=1, ${foo}, concat(indexed-repeat(., ${repeat}, position(..)-1))
fails DAG check because detects reference to self (.), even though not in fact self-referencing because actually referencing result from previous iteration.
Steps to reproduce the problem
run form with repeat group that uses an accumulator in this manner. Form cannot run because DAG check incorrectly detects as self-reference cycle
Expected behavior
no error
Other information
no way to determine this is not in fact a self-reference except by dynamically evaluating the expression, to see that the resulting XML element is actually different (ie position(..)-1))
As I understand it, you are trying to accumulate results across repeats. The form here demonstrates how I would do that. The important expression is join(" ", /data/my-repeat[position(..) <= position(current()/..)]/foo)
.
I find indexed-repeat
more complicated to reason about than raw XPath queries so I try to avoid it.
I'm also not exactly clear on what you're trying to concatenate. Are you accumulating results into a node that is also a question?
In the provided example, yes I was trying to accumulate results, which you correctly point out can probably be accommodated with a join(...) instead. However there are still cases when you want to reference previous iterations, eg prefilling values from the previous iteration (see https://forum.opendatakit.org/t/previous-response-pre-loaded-for-the-same-question-from-a-previous-iteration-of-a-repeat/20706/4)
The issue is that indexed-repeat() is the documented function for referencing specific values in a repeat group, and therefore - as defined - should work equally well within and outside a repeat group. I believe it probably can, but validate is 'interfering' by throwing a bogus cyclic dependency check, essentially based on the (false) premise in this case that a specified element node name is always unique, whereas it is not when it comes to repeat groups. Note that Enketo does not throw a cyclic dependency error here.