XLSForm / pyxform

A Python package to create XForms for ODK Collect.
BSD 2-Clause "Simplified" License
77 stars 134 forks source link

First indexed-repeat() argument is sometimes relative but should always be absolute #569

Open MartijnR opened 2 years ago

MartijnR commented 2 years ago

Software and hardware versions

pyxform v1.7.0 as used by https://getodk.org/xlsform/

Problem description

  1. Some exotic usage of indexed-repeat tricks pyxform in generating a relative first argument of indexed-repeat, e.g. indexed-repeat(../node, /data/repeat, 1) instead of indexed-repeat(/data/repeat/node, /data/repeat, 1).
  2. Presumably the same bug also seems to trick non-indexed-repeat paths from become absolute when they should be relative.

Only non-sensical usages have been found to produce this issue (so far), i.e. using indexed-repeat() inside a repeat when it's better to not use indexed-repeat() at all. It is however, difficult to prevent users from doing such things as it requires a fairly advanced understanding of that (weird, imho) function.

Steps to reproduce the problem

See xlsform and the same copied below:

type name label calculation
begin repeat rep    
integer one Enter number  
text a   if(indexed-repeat(${one},${rep},position(..)-1)=3 and indexed-repeat(${one},${rep},position(..)-1)!='', indexed-repeat(${one},${rep},position(..)-1),0)
text b   if(indexed-repeat(${one},${rep},position(..)-1)=3 and ${one} != '', indexed-repeat(${one},${rep},position(..)-1),0)
end repeat      

Expected behavior

a. Node a should have 3 /data/rep/one paths in the output for all ${one} references. The second path is incorrect (../one). b. Node b should generate and ../one in the output for the second ${one} reference and /data/rep/one for the 1st and 3rd ${one} reference. It incorrectly generates /data/rep/one for the 2nd reference.

Other info

See https://github.com/XLSForm/pyxform/pull/485 and in particular the last comment by @lognaturel (that I cannot link to for some reason).