Skip to content

Allow declaring that multiple Entities should be created/updated #800

@lognaturel

Description

@lognaturel

ODK forum discussion · ODK forum discussion of XForms spec

The entities sheet MAY include multiple Entity declaration rows, provided that no two rows reference the same list_name.

Survey sheet save_to prefixes

If the entities sheet has more than one Entity declaration, then each save_to value on the survey sheet MUST be prefixed with a list_name followed by #, where the prefix matches a list_name in the entities sheet.

Example:

  • households#hhid
  • participants#first_name

The string after # is the Entity property name.

See the XForms spec for rules and validation related to save_to.

Entity-level expressions and repeats

Entity-level expressions are expressions on the entities sheet, currently label, create_if, update_if, and entity_id.

If an Entity declaration's associated save_tos are in a repeat, Entity-level expressions MUST be evaluated by clients separately for each repeat instance (so generated XForms references must be relative).

Additionally, each node reference in an Entity-level expression MUST resolve to a single unambiguous node for each repeat instance. A node reference is valid only if

  • The referenced node is within the repeat subtree, or
  • The referenced node is outside the repeat subtree and is not contained within any repeat that is not an ancestor of the Entity declaration’s repeat.

In other words, the repeat-ancestor chain of the referenced node MUST be a prefix of the repeat-ancestor chain of the Entity declaration container.

If an Entity-level expression violates these constraints, the form is invalid.

Example

entities sheet for a form that creates Entities in the households and participants lists:

list_name label
households ${hhid}
participants concat(${first_name}, " ", ${last_name}, "(", ${hhid}, ")")

survey sheet:

type name label save_to calculation
text hhid Household ID households#hhid
geopoint hh_location Household location households#geometry
begin_repeat member Member
text first_name Member first name participants#first_name
text last_name Member last name participants#last_name
calculate member_hh participants#hhid ${hhid}
calculate hh_link participants#hh ../meta/entity/@id
end_repeat member

This example would result in a top-level Entity declaration to create Entities in the households list and an Entity declaration in the member repeat to create Entities in the participants list.

See #816 for proposed syntax to use instead of ../meta/entity/@id. pyxform will be deciding where to put the entity block so writing relative expressions will be hard.

Notes

This specification does not define automatic relationships between Entities declared in nested containers. Relationships, if required, MUST be expressed as normal entity properties (e.g. saving a parent entity ID into a child entity property).

An Entity property MAY be interpreted as a relationship by configuration.

The restriction that list_name values on the entities sheet must be unique exists to keep XLSForm authoring simple. Future versions of the XLSForm specification may introduce an additional identifier (e.g., entity_name) to allow multiple Entity declarations targeting the same Entity List within a single form. For now, users with this need can either have multiple forms (e.g. Register parent and Register child that both save to the people list) or multiple lists (e.g. parent and child lists).

Pyxform implementation notes

For each list_name declared on the entities sheet, pyxform MUST generate exactly one Entity declaration in the XForm.
pyxform MUST place the declaration at the container level that “covers” all of that list’s save_to fields, without crossing invalid repeat boundaries. Sometimes there will be multiple groups in the hierarchy in which pyxform could put the Entity declaration without violating XForms rules. Pyxform should put it somewhere deterministic (e.g. the highest or lowest possible).

Examples:

  • If all households#... fields are at the root, pyxform generates the households Entity declaration at the root.
  • If all participants#... fields are inside a repeat /data/member, pyxform generates the participants Entity declaration inside that repeat.
  • If some participants#... fields are inside a repeat and others are outside that repeat, the form is invalid (because there is no placement that satisfies XForms repeat scoping).

A form is invalid if any of the following are true:

  • The entities sheet contains more than one row with the same list_name.
  • The entities sheet contains more than one row and a save_to value is missing a list_name# prefix.
  • A save_to prefix does not match any list_name declared on the entities sheet.
  • For any given list_name, there does not exist a single container placement for that list’s Entity declaration that satisfies:
    • the “nearest ancestor with an Entity declaration” association rule, and
    • the repeat scoping rules from the XForms specification.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions