# Filtering values in a repeat, in another repeat. indexed-repeat issue and Enketo vs Collect/webforms difference in behaviour

**URL:** <https://forum.getodk.org/t/filtering-values-in-a-repeat-in-another-repeat-indexed-repeat-issue-and-enketo-vs-collect-webforms-difference-in-behaviour/56082>\
**Category:** Support\
**Tags:** form-design, odk-webforms, odk-collect, odk-xlsform, enketo\
**Created:** [August 4, 2025, 10:54am UTC](https://forum.getodk.org/t/filtering-values-in-a-repeat-in-another-repeat-indexed-repeat-issue-and-enketo-vs-collect-webforms-difference-in-behaviour/56082 "2025-08-04T10:54:05Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![ahblake](https://getodk.b-cdn.net/user_avatar/forum.getodk.org/ahblake/32/22392_2.png) [@ahblake](https://forum.getodk.org/u/ahblake)\
**Post date:** [August 4, 2025, 10:54am UTC](https://forum.getodk.org/t/filtering-values-in-a-repeat-in-another-repeat-indexed-repeat-issue-and-enketo-vs-collect-webforms-difference-in-behaviour/56082/1 "2025-08-04T10:54:06Z")

</div>

Continuing from my troubles with ~~tribbles~~ [dynamic repeat labels](https://forum.getodk.org/t/dynamic-repeat-labels-collect-v-enketo-v-web-forms/56036), now I'm trying to filter the contents of a repeat... dynamically

**1. What is the issue? Please be detailed.**  
I have a form where the enumerator selects one item, then via a repeat reports a variable number of findings against it. The findings (child) are identified from a select one, and each is assigned to a parent category via a field against the choice/entity list. Each response against the finding has an associated severity value that is looked up.

I would like to summarise the findings in a parent repeat at the end of the form, filtering the child findings according to which parent they belong to, as well as returning the maximum severity for that parent.

Outside of a repeat I have working logic in Collect/Enketo/Webforms, however you have to select the parent / hard code the parent, and I wish to have a dynamically sized array for varying parent lists.

I can count the parent items in the choice/entity list and create a repeat with that many elements and then iterate through the list [using `position()`](https://forum.getodk.org/t/xml-xpath-iterating-through-a-list-enketo-works-great-but-odk-collect-shows-error/37182) \[1\]. The repeat count is correct and each repeat element correctly shows the parent value that is looked up in turn.

However, the join/max/count calculations that work outside a repeat don't work in the repeat, so I tried to write them differently and filter the repeat values with `indexed-repeat` to count/join/find maximum. This works in Enketo\[2\], but in Web Forms every repeat element returns the outcome for the first item in the choice list.

eg a count (`join` and `max` are much the same) in the parent repeat;

> count(${repeat5}[finding\_parent = indexed-repeat(${calculate39}, ${repeat31}, position(..))])

- repeat5 is the child repeat
  - finding\_parent is the lookup of the selected child category's parent

- calculate39 is the lookup for the parent name value in the parent repeat, this works fine in Collect/Enketo/Webforms
  - `instance('parent')/root/item[name != ''][position()=${calculate38}]/name`
    - calculate38 returns `position(..)` for the parent summary repeat

- repeat31 is the parent repeat where I am attempting to build the summary

**2. What steps can we take to reproduce this issue?**  
Test the attached form in Enketo/Web forms/Collect

**3. What have you tried to fix the issue?**  
I have searched the forum & docs but it's mostly about a 1:1 relationship of using a value from repeat-a element x in repeat-b element x, I can't find anything that pertains to actually **filtering** the content of a repeat to combine multiple values from a repeat into a different repeat when writing expressions.

I'm especially stymied as it does evaluate properly in Enketo, and Collect & Web Forms evaulates without error but always as if the position value = 1 regardless of parent repeat position #, so not usable.

I think I've isolated it to the `indexed-repeat` filter expression eg;

> join(', ' , ${repeat5}[finding\_parent = **indexed-repeat(${calculate39}, ${repeat31}, position(..))**]/group6/select8)

- Replacing `position(..)` with a calculate field that returns `position(..)` breaks the outcome in Enketo and web forms, Collect still evaluates all repeat elements for the first item in the choice list in the filter
- wrapping `position(..)` in `int()` has no effect
- Hard coding the indexed-repeat expression forces it to work for _not_ the first choice item in Collect/Web Forms, which is why I think the indexed-repeat part is the issue. eg;
  - 

> join(', ' , ${repeat5}[finding\_parent = **'air'**]/group6/select8)

- Likewise, hard coding an integer in place of position(..) forces it to work for not the first choice item in Collect/Web Forms
  - 

> join(', ' , ${repeat5}[finding\_parent = **indexed-repeat(${calculate39}, ${repeat31}, 2)**]/group6/select8)

- Flipping the order of field and expression in the filter has no effect
  - 

> join(', ' , ${repeat5}[indexed-repeat(${calculate39}, ${repeat31}, position(..)) **= finding\_parent**]/group6/select8)

- Replacing the indexed-repeat with the field that contains the parent name value doesn't evalulate at all, even though that field should be correct in each repeat element (and does show in a note correctly everywhere).
  - 

> join(', ' , ${repeat5}[finding\_parent = **${calculate39}**]/group6/select8)

- Replacing the indexed-repeat with a separate field (calculate46) that contains the indexed-repeat expression doesn't evalulate at all, even though the field with the indexed-repeat does evaulate correctly and shows in a note correctly for each repeat element.
  - 

> join(', ' , ${repeat5}[finding\_parent = ${calculate46}]/group6/select8)

Hoping @LN will instantly spot a rookie error in my calc logic and it's not a deeper issue 🤣

**4. Upload any forms or screenshots you can share publicly below.**

Example form, first repeat is the child, then there's a manual select to filter values from the child repeat (works), then there's a parent repeat with the issues.

[filtered repeat values for rollup and summary.xlsx](https://forum.getodk.org/uploads/short-url/fyQUpeuo7iorEFs5dimz9rN7cB1.xlsx) (596.7 KB)

* * *

1. Chapeau! This is more efficient than my earlier approach of joining a list of the parent name values and then using `selected-at` and converting from 0 indexed to 1 indexed to pull each one in turn 

2. Mostly! You have to add a blank child repeat in order for the parent repeat to include the penultimate element in the outcome, so it doesn't properly work in Enketo either

---

<div class="post-metadata">

**Author:** ![JenniferQ](https://getodk.b-cdn.net/user_avatar/forum.getodk.org/jenniferq/32/29022_2.png) [@JenniferQ](https://forum.getodk.org/u/JenniferQ)\
**Post date:** [August 4, 2025, 2:17pm UTC](https://forum.getodk.org/t/filtering-values-in-a-repeat-in-another-repeat-indexed-repeat-issue-and-enketo-vs-collect-webforms-difference-in-behaviour/56082/2 "2025-08-04T14:17:22Z")

</div>

Hi @ahblake!

You can try using `current()` in `calculate40`.

**From this:**  
`count(${repeat5}[finding_parent = indexed-repeat(${calculate39}, ${repeat31}, position(..))])`

**To this:**  
`count(${repeat5}[finding_parent = current()/${calculate39}])`

I've added this calculation to your example:  
[filtered repeat values for rollup and summary - FIXED.xlsx](https://forum.getodk.org/uploads/short-url/fOCqVRn5aJ6QzIAS32Lzi8CrATq.xlsx) (285.7 KB)

This is how it works:

---

<div class="post-metadata">

**Author:** ![ahblake](https://getodk.b-cdn.net/user_avatar/forum.getodk.org/ahblake/32/22392_2.png) [@ahblake](https://forum.getodk.org/u/ahblake)\
**Post date:** [August 5, 2025, 12:07am UTC](https://forum.getodk.org/t/filtering-values-in-a-repeat-in-another-repeat-indexed-repeat-issue-and-enketo-vs-collect-webforms-difference-in-behaviour/56082/3 "2025-08-05T00:07:05Z")

</div>

> [@JenniferQ](#):
>
> **To this:**  
> `count(${repeat5}[finding_parent = current()/${calculate39}])`

Ah thank you! SO much simpler. No idea why a standalone indexed-repeat evaluates correctly but when used in the filter it doesn't 🤷

I had seen the `current()` operator, but in the context where it wrapped `position(..)` like this [example](https://docs.getodk.org/form-logic/#dynamic-defaults-in-repeats) in the docs which also a kind of repeat filter (filter to the previous repeat element only), not sure why I discarded that approach.

The problem now is that Enketo won't load the modified version (which works in Collect & Web forms), so no edits could be made in Central (until Web forms has further features added).

> FormLogicError: Could not evaluate: count( /model/instance[1]/data/repeat5 [finding\_parent = /model/instance[1]/data/repeat31/calculate40/ ../calculate39 ]), message: Failed to execute 'createExpression' on 'XPathEvaluator': The string './data/repeat31/calculate40/' is not a valid XPath expression.

removing the count expression cascades the error to the next expression

> FormLogicError: Could not evaluate: join(', ' , /model/instance[1]/data/repeat5 [finding\_parent = /model/instance[1]/data/repeat31/calculate41/ ../calculate39 ]/calc\_finding\_ID), message: Failed to execute 'createExpression' on 'XPathEvaluator': The string './data/repeat31/calculate41/' is not a valid XPath expression.

---

<div class="post-metadata">

**Author:** ![ahblake](https://getodk.b-cdn.net/user_avatar/forum.getodk.org/ahblake/32/22392_2.png) [@ahblake](https://forum.getodk.org/u/ahblake)\
**Post date:** [August 5, 2025, 4:56am UTC](https://forum.getodk.org/t/filtering-values-in-a-repeat-in-another-repeat-indexed-repeat-issue-and-enketo-vs-collect-webforms-difference-in-behaviour/56082/4 "2025-08-05T04:56:18Z")

</div>

Tried a couple of things to see if Enketo will play nice and also not break Collect/WebForms again.

- flipping the filter has no effect on Enketo loading (doesn't) or Web Forms working (still does)
- replacing the current/field filter with the entire instance lookup....WORKS EVERYWHERE 🎊 🥳
  - 

> join(', ' , ${repeat5}[finding\_parent = **current()/${calculate39}**]/calc\_finding\_ID)

  - 

> join(', ' , ${repeat5}[finding\_parent = **instance('parent')/root/item[name != ''][position()=position(current()/..)]/name**]/calc\_finding\_ID)
