ODK XForms Specification (original) (raw)

Entities

Version 2024.1.0

⚠️ In this specification, collections of Entities are referred to as Datasets. The term “Entity List” is generally recommended instead of “Dataset” in text that is intended for users rather than developers.

Introduction

This specification is a sub-specification of the ODK XForms Specification. It describes a semantic layer that identifies the subject of a form (“Entity”) and its properties. Consumers that implement this specification can process form submissions to extract Entity information based on the directives provided in the form definition.

Versions

Version Changes
2024.1.0 Adds metadata to support clients with offline Entity representations. Clients should only apply creates and updates offline for forms with this version or higher.
2023.1.0 Adds Entity updates from form submissions, still with Entities only created or updated on the server
2022.1.0 Adds Entity creation from form submissions, with Entities only created on the server (no offline Entity creation)

See section on Versioning

Glossary

Entity: A uniquely-identified thing that a form is about.

Dataset: A set of Entities of the same type.

Entity Property: A named value that belongs to an Entity.

Immutable System Property: An Entity Property that is used by the system and that can’t be changed (dataset, id)

Mutable System Property: An Entity Property that is used by the system and that can be changed (label)

User-defined Property: Properties with arbitrary names defined by the form designer

Entity Actions: Actions that can be taken on Entities (create, update)

Example of an entity-creating form

Note: the only change needed to prevent offline entity creation or to support older clients is to change the entities-version to 2022.1.0

<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:entities="http://www.opendatakit.org/xforms/entities" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:jr="http://openrosa.org/javarosa" xmlns:odk="http://www.opendatakit.org/xforms" xmlns:orx="http://openrosa.org/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <h:head>
    <h:title>Trees registration</h:title>
    <model odk:xforms-version="1.0.0" entities:entities-version="2024.1.0">
      <instance>
        <data id="trees_registration" version="2025110901">
          <location/>
          <species/>
          <meta>
            <instanceID/>
            <entity dataset="trees" id="" create="true">
              <label/>
            </entity>
          </meta>
        </data>
      </instance>
      <bind nodeset="/data/location" type="geopoint" entities:saveto="geometry" />
      <bind nodeset="/data/species" type="string" entities:saveto="species" />

      <bind jr:preload="uid" nodeset="/data/meta/instanceID" readonly="true()" type="string"/>

      <bind nodeset="/data/meta/entity/@id" type="string"/>
      <setvalue event="odk-instance-first-load" ref="/data/meta/entity/@id" value="uuid()"/>
      <bind nodeset="/data/meta/entity/label" calculate="/data/species"  type="string"/>
    </model>
    ...

Example of an entity-updating form

Note: to prevent offline entity updates or to support older clients, change the entities-version to 2023.1.0 and omit the trunkVersion and branchId attributes on entity

<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jr="http://openrosa.org/javarosa" xmlns:orx="http://openrosa.org/xforms" xmlns:odk="http://www.opendatakit.org/xforms" xmlns:entities="http://www.opendatakit.org/xforms/entities">
    <h:head>
        <h:title>Trees circumference update</h:title>
        <model odk:xforms-version="1.0.0" entities:entities-version="2024.1.0">
            <instance>
                <data id="trees_update" version="20250108145123">
                    <tree/>
                    <circumference/>
                    <meta>
                        <instanceID/>
                        <entity dataset="trees" id="" update="1" baseVersion="" trunkVersion="" branchId="">
                            <label/>
                        </entity>
                    </meta>
                </data>
            </instance>

            <instance id="trees" src="jr://file-csv/trees.csv"/>

            <bind nodeset="/data/tree" type="string"/>
            <bind nodeset="/data/circumference" type="int" entities:saveto="circumference_cm"/>

            <bind jr:preload="uid" nodeset="/data/meta/instanceID" type="string" readonly="true()"/>

            <bind nodeset="/data/meta/entity/@id" type="string" readonly="true()" calculate=" /data/tree "/>
            <bind nodeset="/data/meta/entity/@baseVersion" calculate="instance('trees')/root/item[name= /data/tree ]/__version" type="string" readonly="true()"/>
            <bind nodeset="/data/meta/entity/@trunkVersion" type="string" calculate="instance('trees')/root/item[name=/data/tree]/__trunkVersion" />
            <bind nodeset="/data/meta/entity/@branchId" type="string" calculate="instance('trees')/root/item[name=/data/tree]/__branchId" />

            <bind nodeset="/data/meta/entity/label" calculate="concat( /data/circumference , &quot;cm &quot;, instance('trees')/root/item[name= /data/tree ]/species)" type="string" readonly="true()"/>
        </model>
        ...

Referencing existing entities in forms

Servers implementing this specification must serve datasets as CSV files which can be attached to forms as external secondary instances. Entity CSVs:

Namespacing

This specification uses the http://www.opendatakit.org/xforms/entities namespace for attributes added to nodes defined by the ODK XForms spec. In this document, the corresponding prefix used is entities.

Additions to the main instance are NOT namespaced. The specification describes exact XPath paths that consumers must look for.

Versioning

Consumers of the ODK XForms specification may opt into this entities specification but don’t have to. For this reason, the entities layer is versioned separately from ODK XForms using the entities-version attribute in the http://www.opendatakit.org/xforms/entities namespace.

The specification is versioned using a YYYY.NN.MM scheme:

The YYYY.NN components of the version are only changed when a consumer built for an earlier version can no longer correctly use a form definition. For example, a version update will likely be made when multiple entities per form are supported.

Consumers MUST reject forms with a version code that is newer than what they can process.

Declaring that a form creates entities

Entities are declared in the entity element in the meta block of the form definition. For entity creation, the entity element:

Declaring that a form updates entities

Added in spec version 2023.1.0

Entity updates are declared in the entity element in the meta block of the form definition. For entity updates, the entity element:

When a consumer of this specification applies an entity update, it:

Added in spec version 2024.1.0

The entity element for an offline-capable update additionally:

Identifying entity properties

The entities:saveto bind attribute declares that the form field specified by the nodeset attribute on the bind should be saved as an Entity Property. The attribute’s value is the Entity Property’s name and and has the following restrictions:

The set of all Entity Properties defined across all forms that populate a specific Dataset define that Dataset’s schema. New properties can be introduced by forms that create or update Entities.