0% found this document useful (0 votes)
69 views74 pages

XLSForm

Uploaded by

kamaldine08
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
69 views74 pages

XLSForm

Uploaded by

kamaldine08
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 74

XLSForm.

org
 XLSForm.org
 info@xlsform.org

What is an XLSForm?
XLSForm is a form standard created to help simplify the authoring of forms in Excel.
Authoring is done in a human readable format using a familiar tool that almost everyone
knows - Excel. XLSForms provide a practical standard for sharing and collaborating on
authoring forms. They are simple to get started with but allow for the authoring of
complex forms by someone familiar with the syntax described below.

The XLSForm is then converted to an ODK XForm, a popular open form standard, that
allows you to author a form with complex functionality, like skip logic, in a consistent way
across a number of web and mobile data collection platforms.

Basic format
Each Excel workbook usually has two worksheets: survey and choices. A third optional
worksheet, called settings, can add additional specifications to your form and is
described below.

The survey worksheet


This worksheet gives your form its overall structure and contains most of the content of
the form. It contains the full list of questions and information about how they should
appear in the form. Each row usually represents one question; however, there are certain
other features described below that you can add to the form to improve the user
experience.

The choices worksheet


This worksheet is used to specify the answer choices for multiple choice questions. Each
row represents an answer choice. Answer choices with the same list name are
considered part of a related set of choices and will appear together for a question. This
also allows a set of choices to be reused for multiple questions (for example, yes/no
questions).
Setting up your worksheets
Both of these worksheets have a set of mandatory columns that must be present for the
form to work. Additionally, each worksheet has a set of optional columns that allow
further control over the behavior of each entry in the form, but are not essential to have.
Every entry must have values for each of the mandatory columns, but the optional
columns may be left blank.

 The survey worksheet has 3 mandatory columns: type, name, and label.
o The type column specifies the type of entry you are expecting for the
question.
o The name column specifies the unique variable name for that entry. No
two entries can have the same name. Names have to start with a letter or
an underscore. Names can only contain letters, digits, hyphens,
underscores, and periods. Names are case-sensitive.
o The label column contains the actual text you see for the question in the
form. Alternatively, label translation columns can be used.
type name label
today today
select_one gende
Respondent's gender?
gender r
integer age Respondent's age?
surveychoicessettings
 The choices worksheet has 3 mandatory columns as well: list name, name,
and label.
o The list name column lets you group together a set of related answer
choices, i.e., answer choices that should appear together under a
question.
o The name column specifies the unique variable name for that answer
choice.
o The label column shows the answer choice exactly as you want it to
appear on the form. Alternatively, label translation columns can be used.
list_name name label
transgende
gender Transgender
r
gender female Female
gender male Male
gender other Other
surveychoicessettings

The columns you add to your Excel workbook, whether they are mandatory or optional,
may appear in any order. Optional columns may be left out completely. Rows or columns
may be left blank to aid readability, but data after 20 adjacent blank columns or rows on
a sheet will not be processed. All .xlsx file formatting is ignored, so you can use dividing
lines, shading, and other font formatting to make the form more readable.
One thing to keep in mind when authoring forms in Excel is that the syntax you use must
be precise. For example, if you write Choices or choice instead of choices, the form
won't work.

Question types
XLSForm supports a number of question types. These are just some of the options you
can enter in the type column in the survey worksheet in your XLSForm:
Question type Answer input
integer Integer (i.e., whole number) input.
decimal Decimal input.
range Range input (including rating)
text Free text response.
select_one [options] Multiple choice question; only one answer can be selected.
select_multiple [options] Multiple choice question; multiple answers can be selected.
select_one_from_file [file] Multiple choice from file; only one answer can be selected.
select_multiple_from_file
Multiple choice from file; multiple answers can be selected.
[file]
rank [options] Rank question; order a list.
Display a note on the screen, takes no input. Shorthand for
note
type=text with readonly=true.
geopoint Collect a single GPS coordinate.
geotrace Record a line of two or more GPS coordinates.
Record a polygon of multiple GPS coordinates; the last point is
geoshape
the same as the first point.
date Date input.
time Time input.
dateTime Accepts a date and a time input.
image Take a picture or upload an image file.
audio Take an audio recording or upload an audio file.
background-audio Audio is recorded in the background while filling the form.
video Take a video recording or upload a video file.
file Generic file input (txt, pdf, xls, xlsx, doc, docx, rtf, zip)
Scan a barcode, requires the barcode scanner app to be
barcode
installed.
calculate Perform a calculation; see the Calculation section below.
acknowledge Acknowledge prompt that sets value to "OK" if selected.
A field with no associated UI element which can be used to
hidden
store a constant
xml-external Adds a reference to an external XML data file

GPS
For example, to collect the name and GPS coordinates of a store, you would write the
following:

type name label


store_nam
text What is the name of this store?
e
geopoin
store_gps Collect the GPS coordinates of this store.
t
surveychoicessettings

To collect a line or shape of GPS coordinates, you can use one of the following:

type name label hint


Please walk along the pipeline and record the coordinates of
geotrace pipe Pipeline
each corner point
geoshap Please walk along the border and record the coordinates of
border Border
e each corner point
surveychoicessettings
See the question_types XLSForm for a look at each question type being used in a form.

GPS with accuracyThreshold


When recording GPS coordinates in ODK Collect, ODK collect automatically collects the
gps when an accuracy level of 5 meters or less is reached. You can change this default
behaviour by specifying an accuracyThreshold; this could be less than 5m or more than
5m. You will need to add a column with heading body::accuracyThreshold on the
survey sheet of your XLSForm. Then specify your preferred accuracy threshold value for
this column on your geopoint question, as in the example shown below:
type name label body::accuracyThreshold
geopoin Collect the GPS coordinates of this
store_gps 1.5
t store.
surveychoicessettings
See gps_accuracy_threshold form for an example that uses this attribute.

Multiple choice
XLSForm supports both select_one (select only one answer)
and select_multiple (select multiple answers) questions. Writing a multiple choice
question requires adding a choices worksheet to your Excel workbook. Here is an
example of a select_one question:
type name label
select_one yes_no likes_pizza Do you like pizza?
surveychoicessettings
nam
list name label
e
yes_no yes Yes
yes_no no No
surveychoicessettings
Note that the yes_no in the survey worksheet must match the yes_no in the list
name column in the choices worksheet. This ensures that the form displays the correct
list of answer choices for a particular question.

We can also add multiple choice questions that allow multiple answers to be selected,
like so:

type name label


select_multiple
favorite_toppings What are your favorite pizza toppings?
pizza_toppings
surveychoicessettings

list name name label


pizza_topping
cheese Cheese
s
pizza_topping
pepperoni Pepperoni
s
pizza_topping
sausage Sausage
s
surveychoicessettings

Choice names
The name column of the choices sheet defines the values that will be saved when each
choice is selected during data collection. Choice names for select_multiple must not
contain spaces because spaces are used as a separator when an answer with multiple
selected choices is saved. Choice names for select_one questions may contain spaces.
However, we recommend avoiding them to make analysis easier. Additionally, this
makes it possible to convert the question to a select_multiple in a future form version.
In general, choice names should be unique within a single choice list. If two choices from
the same list have the same name, they will be impossible to tell apart in analysis. If you
have duplicate choice names, you will get an error, and your form will not be converted.
However, it may sometimes be appropriate to have duplicate choice names. An example
would be if you use a cascading select, and the choices with the same name are
differentiated by a preceding question. If you do need to use duplicate choice names,
you can suppress the error by using the allow_choice_duplicates setting:
allow_choice_duplicates
yes
surveychoicessettings
Specify other
For multiple choice questions, surveys often include an option of marking other when
their answer choice is not listed. Then, they are usually asked to specify the other option.
This is possible through XLSForm by including or_other after the answer choice list
name in the survey worksheet. The choices worksheet stays the same. See below:
type name label
select_multiple pizza_toppings What are your favorite pizza
favorite_topping
or_other toppings?
surveychoicessettings

list name name label


list name name label
pizza_topping
cheese Cheese
s
pizza_topping
pepperoni Pepperoni
s
pizza_topping
sausage Sausage
s
surveychoicessettings
Click on the link to look at the complete pizza_questionnaire.
Caveat
When you export data using this or_other option, in the favorite_topping column, you
will see a value other. A separate column will have the answer for the questions in which
the user selected other. This makes data analysis more cumbersome, so we do not
recommend the or_other construct for large scale data collection efforts. See
the Relevant section below for an alternative method more appropriate for large scale
projects.

Location widget
A user may want to select a location from a map view during data collection. To enable
this feature, you need to add the map or quick map appearance attribute to
a select_one question. The choices sheet will also need a geometry column added for
the list_name noted in the select_one questions. The geometry must be specified using
the ODK format. This feature is only currently available on ODK Collect. See below:
list name name label geometry
list name name label geometry
36.7965483 -1.3182517 0
site shofco Shofco
0
36.7967088 -1.3170903 0
site gemkam Gemkam Medical Clinic
0
36.7955008 -1.3167834 0
site silanga Silanga Pharmacy
0
36.7990986 -1.3179328 0
site undugu Undugu Medical Clinic
0
surveychoicessettings
Multiple choice from file
The options in a multiple choice question can also be taken from a separate file instead
of the choices sheet. This is particularly useful if the options are dynamic or if the list of
options is used in multiple surveys. Three types of files are supported: CSV, XML, and
GeoJSON files. See usage examples below:

nam
type label choice_filter
e
select_multiple_from_file In which countries did you
liv
country.csv live?
In which country do you live
select_one_from_file countries.xml cou
now?
select_one_from_file countries.xml cit What is the closest city? name=${cou}
select_one_from_file
hh Select household number
households.csv
surveychoicessettings

type name label appearance


select_one_from_file Select the health facility
site map
health_facility.geojson visited
surveychoicessettings
The files require a specific format. A CSV file requires a name and label column which
represent the value and label of the options. An XML file requires a structure as shown
below:
<root>
<item>
<name/>
<label/>
...
</item>
</root>

A GeoJSON requires each feature, or point, to have an id and title property, or an


attribute of the point. The GeoJSON must be defined by a single top-level
FeatureCollection, and it currently only works for point geometry, as noted in detail on
the ODK documentation site.

CSV, XML, and GeoJSON files may have additional columns, XML nodes, or features
and custom properties as long as the above-mentioned basic requirements are met.

If the CSV, XML, or GeoJSON files use different names for the choice name and label,
add a column to the survey sheet named parameters, and specify the custom names
with the value and label parameters. See usage examples below:
nam
type label parameters
e
select_multiple_from_file In which countries did
liv value=ccode
country.csv you live?
select_one_from_file cou In which country do label=cname
nam
type label parameters
e
countries.xml you live now?
select_one_from_file Select household value=housenum,
hh
households.csv number label=housename
surveychoicessettings

nam
type label appearance parameters
e
Select the
select_one_from_file value = id, label
site health facility map
health_facility.geojson = name
visited
surveychoicessettings
Note that, this question type is generally the preferred way of building select questions
from external data as it is the most versatile and works across applications. However, if
your external data file consists of many thousands of lines, please test carefully whether
the performance is satisfactory on the lowest spec device you intend to use. If it is too
slow, consider using External Selects or Dynamic selects from preloaded data if your
data collection application supports it.

Rank
The rank widget can be used to let respondents order a list of options. The answer is
saved as an ordered, space-separated list of option values where all options are always
included. The syntax is very similar to multiple-choice questions.

type name label


rank topping Order pizza toppings with your favorite on
pizza_toppings s top
surveychoicessettings

list name name label


pizza_topping
cheese Cheese
s
pizza_topping
pepperoni Pepperoni
s
pizza_topping
sausage Sausage
s
surveychoicessettings
To prevent bias it is often recommended to use the randomize feature in conjunction with
this widget.

Range
To restrict integer or decimal inputs to a specific range, you can use the range question.
This question can be used with 3 optional space-separated parameters: start, end,
and step in a parameters column. The default values are 0, 10, and 1 respectively. The
example below will create a question that allows input from 0 until 17 with a step of 1.
Using a decimal step will result in decimal values being collected.
type name label parameters
rang What is the age of the
amount start=0 end=17 step=1
e child?
surveychoicessettings
To display a range question as a rating widget using stars, you can add the rating
appearance as shown below:
nam
type label appearance parameters
e
range rated What rating do you give? rating start=1 end=5 step=1
surveychoicessettings

Image
To upload an image file the image question type can be used. To ensure the images are
not too large, you can optionally set the max-pixels parameter which will automatically
downsize the uploaded image to match the largest side of the image with the pixel value
provided.
type name label parameters
imag Upload an
img max-pixels=1000
e image
surveychoicessettings

Audio recording quality


Certain clients use a value for quality in the parameters column to configure audio
recording quality for question types audio or background-audio. Both question types
accept quality values voice-only, low and normal. audio additionally accepts
a quality of external to specify that an external application should be used for
recording.
type name parameters
audio animal_sound quality=normal
surveychoicessettings

Metadata
XLSForm has a number of data type options available for meta data collection:
Metadata
Meaning
type
start Start date and time of the survey.
end End date and time of the survey.
today Day of the survey.
deviceid Unique client identifier. Can be user-reset.
phonenumber Phone number (if available).
username Username configured (if available).
email Email address configured (if available).
Log enumerator behavior during data
audit
entry

Note that some metadata fields only apply for mobile phone-based forms.

For example, if you wanted to collect all of these types of metadata, put the following in
your form (typically at the beginning, but can be at any point of your form):

type name label parameters


start start
end end
today today
deviceid deviceid
phonenumbe phonenumbe
r r
username username
email email
audit audit [optional, see below]
surveychoicessettings
Notice that there are no labels associated with the metadata question types. This is
because the phone captures these variables automatically. These questions will not
appear on the screen of the phone, but you will see them when viewing your submitted
survey data. The Tutorial XLSForm shows how metadata is used in a form.
Audit enumerator behavior and location tracking
Note: For now this feature is only available in Collect, but not in Enketo webforms.
The audit metaquestion will enable ODK Collect to log how people navigate through a
form during data entry. For example, this can be used to measure how much time an
enumerator took to fill in a question, responses that were edited later on, or when the
form was saved.
Optionally, the audit metaquestion can be configured to also record the location of the
enumerator throughout the interview. This may be useful for quality control or to record
exact paths taken between each respondents. To do this, add a column
called parameters to your form and enter three required parameters: location-
priority, location-min-interval, and location-max-age.

This example below would collect the precise GPS location every 180 seconds and will
discard coordinates collected more than 300 seconds ago.
typ
name label parameters
e
location-priority=high-accuracy location-min-interval=180 location-
audit audit
max-age=300
surveychoicessettings
See this page in the ODK Collect documentation for full details about
the audit metaquestion, available location tracking parameters, and the format of
the audit.csv log file created for each submission.

External XML data


For advanced users, who need to perform complex queries on external data without
restrictions, an external XML data file can be added with question type xml-external.
The value in the name column can be used to refer to this data in any formula (e.g. for a
calculation, constraint, relevant, or choice_filter) using the instance('name') function. A
file with the same name and the .xml extension should be uploaded with the form. See
below for an example that requires uploading a file called houses.xml with the form.
If your external data file consists of many thousands of lines, please test carefully
whether the performance is satisfactory on the lowest spec device you intend to use. If it
is too slow, consider using External Selects instead if your data collection application
supports this.
type name label calculation
xml-
houses
external
How many
integer rooms
rooms?
count(instance('houses')/house[rooms =
calculate count
current()/../rooms ])
surveychoicessettings

Hints
Regular hints
Sometimes you want to add a small hint to a question on your form, instructing the user
how to answer the question, but you don't want the hint to be part of the question itself.
It’s easy to add hints to questions in XLSForms. Simply add a hint column and add your
hint message. See below for an example.
type name label hint
Look on the signboard if the store has
text name What is the name of this store?
a signboard.
geopoin Collect the GPS coordinates of
geopoint
t this store.
type name label hint
surveychoicessettings
The Tutorial XLSForm provides more examples of questions with hints.

Guidance hints
There is a special kind of hint that is normally not shown in the form. It is only shown in
special views. An example would to show these hints on print-outs or during a training for
enumerators. These hints are called guidance hints and can be added in
the guidance_hint column. See below for an example.
nam
type label guidance_hint relevant
e
integer age Age?
This will only be shown for age >
text name Name? ${age} > 18
18.
surveychoicessettings

Formulas
Formulas are used in the constraint, relevant, calculation, and trigger columns and
optionally also in the default, and required columns. Formulas allow you to add additional
functionality and data quality measures to your forms.
Formulas are composed of functions and operators (+,*,div,etc.). A well-documented full
list of operators and functions can be found in the ODK documentation. For the
technically inclined, the underlying XForms specification is the actual source document
for the supported functions.

Constraints
One way to ensure data quality is to add constraints to the data fields in your form. For
example, when asking for a person's age, you want to avoid impossible answers, like -22
or 200. Adding data constraints in your form is easy to do. You simply add a new column,
called constraint, and type in the formula specifying the limits on the answer. In the
example below, the answer for the person's age must be less than or equal to 150. Note
how the . in the formula refers back to the question variable.
type name label constraint
How old are
integer age . <= 150
you?
surveychoicessettings
In this example, the formula . <= 150 is saying that the value entered . for the question
must be less than or equal to 150. If the user puts 151 or above as the answer, s/he will
not be allowed to move on to the next question or submit the form.
Other useful expressions to use in the constraint column can be found here. Look under
the Operators section.

Constraint message
If you want to include a message with your constraint, telling the user why the answer is
not accepted, you can add a constraint_message column to your form. See the
example below.
type name label constraint constraint_message
intege respondent_ag Respondent's Respondent must be 18 or older
. >=18
r e age to complete the survey.
surveychoicessettings
In this example, if the user enters an age less than 18, then the error message in
the constraint_message column appears. More examples on constraints have been
illustrated in this XLSForm.

Relevant
One great feature of XLSForm is the ability to skip a question or make an additional
question appear based on the response to a previous question. Below is an example of
how to do this by adding a relevant column for a select_one question, using our pizza
topping example from before:
type name label relevant
Do you like
select_one yes_no likes_pizza
pizza?
select_multiple pizza_toppings Favorite ${likes_pizza} =
favorite_topping
or_other toppings 'yes'
surveychoicessettings
In this example, the respondent is asked, “Do you like pizza?” If the answer is yes, then
the pizza topping question appears below. Note the ${ } around the
variable likes_pizza. These are required in order for the form to reference the variable
from the previous question.
In the next example, below, we use relevant syntax for a select_multiple question,
which is slightly different from the select_one question example above.
type name label relevant
Do you like
select_one yes_no likes_pizza
pizza?
select_multiple
Favorite
pizza_toppings favorite_topping ${likes_pizza} = 'yes'
toppings
or_other
What is your
selected(${favorite_topping},
text favorite_cheese favorite type of
'cheese')
cheese?
surveychoicessettings
list name name label
pizza_topping
cheese Cheese
s
pizza_topping
pepperoni Pepperoni
s
pizza_topping
sausage Sausage
s
surveychoicessettings
Since the pizza topping question allows multiple responses, we have to use
the selected(${favorite_topping}, 'cheese') expression, because we want the
cheese question to appear every time the user selects cheese as one of the answers
(regardless of whether additional answers are selected).

Earlier we mentioned there was an alternative method for specifying other for multiple
choice questions which is more appropriate for large scale surveys. This can be done
using the same relevant syntax from the example above:

type name label relevant


What are your
select_multiple
favorite_toppings favorite pizza
pizza_toppings
toppings?
favorite_toppings_othe selected(${favorite_toppings},
text Specify other:
r 'other')
surveychoicessettings

list name name label


pizza_topping
cheese Cheese
s
pizza_topping
pepperoni Pepperoni
s
pizza_topping
sausage Sausage
s
pizza_topping
other Other
s
surveychoicessettings
Note that you must include other as an answer choice in the choices worksheet.

Calculation
Your survey can perform calculations using the values of preceding questions. In most
cases using a calculate type question is appropriate. For example, in the survey below,
we have calculated the tip for a meal and displayed it to the user:
type name label calculation
decimal amount What was the price of the meal?
calculat tip ${amount} * 0.18
type name label calculation
e
note display 18% tip for your meal is: ${tip}
surveychoicessettings
Note that the ${tip} in the last line will be replaced with the actual tip amount when
viewing and filling out the form.
The calculate type calculates text but calculations can also be added to any other
question types. Non-text types can be useful for data analysis, e.g if a date or date-time
is calculated. If no label and no hint is included, the calculation will be hidden. See
example below which is the equivalent of the previous form:
type name label hint calculation
decima What was the price of the
amount
l meal?
text tip ${amount} * 0.18
note display 18% tip for your meal is: ${tip}
surveychoicessettings

And this is an example when a non-text type is needed because of data analysis
requirements:

type name label hint calculation


date day today()
surveychoicessettings
Note that using non-text calculation types has no effect on using the calculation
result within the form itself. This is a common misunderstanding.
If a label or hint is included, the question will be visible on the form and the calculated
value will be shown in the input field or widget. This is generally only recommended
for readonly questions to avoid re-calculating (erasing) a user-entered value. See
example below:
type name label readonly calculation
decima
amount What was the price of the meal?
l
note display 18% tip for your meal is: ${amount} * 0.18
date today Today's date is: true today()
surveychoicessettings

Note the difference with the first form in this section is how the calculated tip value is
displayed. In the first example it was shown in the label and in the last example it is
shown inside a readonly input field.

Trigger
A trigger column can be used to run a calculation only when another visible question
in the form changes. This means that the question that is serving as the trigger has to
have a label or a hint (otherwise it will be hidden). See a simple but very useful example
below:
type name label calculation trigger
Enter the current
integer temp
temperature
dateTim temp_t
now() ${temp}
e s
surveychoicessettings

This will calculate a timestamp immediately after a respondent enters a temperature. If


the user goes back and changes the temperate, the timestamp will be re-calculated.

All the regular calculation features apply to these special value-change-triggered


calculations as well. So you can e.g. use a label or hint to display the calculation
question on the form to the user.

Multiple questions may have the same trigger. See this example, where two calculations
are triggered by the temperature question (one is hidden, and the other is shown):

trigge
type name label calculation readonly
r
Enter temperature in
integer temp
Celsius
dateTim temp_t
now() ${temp}
e s
32 + 1.8 * $
text temp_F Temperature in Fahrenheit ${temp} true
{temp}
calculate temp_K 273.15 + ${temp} ${temp}
surveychoicessettings

In the form above the temp_F question is shown to the user and the temp_K question is
hidden, just as they would be if trigger was not used.

An important and powerful difference with regular calculations is that the calculation
value with a trigger may also be empty, which serves to clear a value from the form.
See example below:
type name label calculation trigger
What is the name of the oldest person
text name
here?
integer age How old is this person? ${name}
surveychoicessettings

If the respondent using this form has entered the name and age of person A and
subsequently finds out there is an older person B, the age field will be cleared as soon as
the name of person B has been entered.
Required
It's simple to mark certain questions as required in your form. Marking them as required
means the user will not be able to move on to the next question or submit the form
without entering an answer for that question.

To make questions required, add a required column to your survey worksheet. Under
that column, mark questions as required by writing yes. See the example below:
constrain
type name label required
t
intege
age How old are you? . <= 150 yes
r
surveychoicessettings

Required message
If you want to customize the message displayed to users when they leave a required
question blank, you can add a required_message column to your form. See the
example below.
type name label required required_message
respondent_ag Sorry, this answer is
integer Respondent's age yes
e required.
surveychoicessettings

Randomize Choices
For any question type that shows a list of choices the shown order of the choices
displayed to the user can be randomized with the parameters column. See below:
type parameters name label
randomize=tru
select_one toppings top Favorite?
e
surveychoicessettings
For reproducible randomization, a seed can be explicitly provided as shown below. To
learn more about the randomization algorithm used, see here.
type parameters name label calculation
once(decimal-date-
calculate sd
time(now()))
select_one randomize=true, seed=$
top Favorite?
toppings {sd}
surveychoicessettings
Note that once() is used to prevent re-randomizing for example when a draft record is
loaded for editing.
Grouping questions
To create a group of questions in your form try the following:

type name label


begin
respondent Respondent
group
text name Enter the respondent’s name
Enter the respondent’s position within the
text position
school.
end group
surveychoicessettings
This is a good way to group related questions for data export and analysis. Notice
how end group doesn't require a name or label, because it is hidden in the form.

Nesting groups within groups


Groups of questions can be nested within one another:

type name label


begin group hospital Hospital
text name What is the name of this hospital?
begin group hiv_medication HIV Medication
have_hiv_medicatio
select_one yes_no Does this hospital have HIV medication?
n
end group
end group
surveychoicessettings
You always have to end the most recent group that was created first. For instance, the
first end group you see closes the HIV medication group, and the second one closes the
beginning hospital group. When working with groups and you keep getting error
messages when trying to upload your form, double-check that for each begin group you
have one end group.

Skipping
One neat feature of XLSForm is the ability to skip a group of questions by combining the
group feature with relevant syntax. If you want to skip a group of questions all at once,
put the relevant attribute at the beginning of a group like follows:

type name label relevant


integer age How old are you?
type name label relevant
begin group child Child ${age} <= 5
Record this child’s mid-upper arm
integer muac
circumference.
select_one
mrdt Is the child’s rapid diagnostic test positive?
yes_no
end group
surveychoicessettings
In this example, the two child group questions (muac and mrdt) will only appear if the
child's age from the first question is less than or equal to five.

Repeats
A user can repeat questions by using the begin repeat and end repeat construct:
type name label
begin repeat child_repeat
text name Child's name
decimal birthweight Child's birthweight
select_one male_female sex Child's sex
end repeat
surveychoicessettings

list name name label


male_female male Male
male_female female Female
surveychoicessettings
In this example, the name, birthweight, and sex fields are grouped together in a repeat,
and the user can collect the same information about multiple children by selecting the
option in the form to add another repeat.
The label column is optional for begin repeat. Assigning a label to a repeat will add the
label as a title to the block of repeat questions in the form.
When a repeat is shown in a table of contents, the label used to represent each repeat is
the label of the first group inside that repeat. In the example below, if a repeat is filled out
with values Preity for first_name, Zinta for last_name and 71 for age, that repeat will
be summarized as "Preity Zinta - 71":
type name label
person_repea
begin repeat
t
begin group person ${first_name} ${last_name} - ${age}
text first_name First name
text last_name Last name
integer age Age
end group
end repeat
type name label
surveychoicessettings
The Delivery Outcome XLSForm is another repeat example.

Fixed repeat counts


Instead of allowing an infinite number of repeats, the form designer can specify an exact
number of repeats by using the repeat_count column:
type name label repeat_count
begin
child_repeat 3
repeat
text name Child's name
decimal birthweight Child's birthweight
end repeat
surveychoicessettings
In the above example, exactly 3 child repeats will be created.

Dynamic repeat counts


The repeat count can be set to an expression that refers to other fields in the form. In the
example below, the number that the user inputs for the num_hh_members field dictates
the number of hh_member repeats added:
type name label repeat_count
num_hh_member Number of household
integer
s members?
begin repeat hh_member ${num_hh_members}
text name Name
integer age Age
end repeat
surveychoicessettings

Only add repeats in certain conditions


Like with groups, all of the questions in a repeat can be skipped based on some
condition. In the example below, the person filling out the form will only be given the
opportunity to add children if they first indicate that there are children to add:
type name label relevant
select_one
has_child Do any children live here?
yes_no
begin repeat child_repeat ${has_child} = 'yes'
text name Child's name
type name label relevant
decimal birthweight Child's birthweight
end repeat
surveychoicessettings

list_name name label


yes_no yes Yes
yes_no no No
surveychoicessettings

Representing zero repeats


By default, the person filling the form will see the questions corresponding to one repeat
before getting the option to add more. To represent 0 repeats, there are three options:

 teach the people filling out the form to delete the first repeat added
 if the exact number of repeats is known ahead of time, use a dynamic repeat
count
 if the exact number of repeats is not known ahead of time, use relevant to only
prompt the user for repeats if there are some to add

Multiple language support


It’s easy to add multiple languages to a form. You simply have to name
your label::language1 (code), label::language2 (code), etc., and your forms will be
available in multiple languages. See the example below. Select a different form language
from the pulldown menu of data collection application (this may be located under
the Menu key). For the form below, English and Español will show up as the possible
options.
type name label::English (en) label::Español (es) constraint
intege ¿Cuántos años
age How old are you? . <= 150
r tienes?
surveychoicessettings
You can also add different language columns for hints and media files by using the
same ::language (code) construct, as shown in the example below. See also
the XLSForm reference table, which includes a list of all column headers that can accept
a language modification.
hint::English
hint::Dutch (nl) image::English (en) image::Dutch (nl)
(en)
a hint een hint old_person_cartoon.png ouwe_strip.png
surveychoicessettings
Form language and user interface language may be the determined separately by the
application and may not match. To facilitate matching both (in the future), it is
recommended, though optional, to add a 2-character language code after the language
name. The official 2-character language codes, called subtags are
published here (search the page with Ctrl-F or Cmd-F).

Media
You can include questions in your form that display images or that play video or audio
files. If using the ODK mobile client for form submission, you need to put the media files
that you want to include in the /odk/forms/formname-media folder on your phone, and
then reference the exact file name in the media column in your form. See below for an
example of how to do this.
type name label image video
note media_example Media example example.jpg example.mp4
surveychoicessettings
Check out the Birds XLSForm which illustrates the use of media files. You can also click
on the link to see the Birds webform .
Media is translatable in the same way as labels and hints as explained in the languages
section.

Pre-loading CSV data


Pre-loading data is done when one wants to reference pre-existing data in a survey form.
You can be able to reference data in your survey form (the survey you are now
authoring), from a pre- existing data in a specific survey form or any other source. For
example if you have pre-existing data from a household survey and you want to collect
follow-up data about the household occupants. You can be able to reference the
household survey data in your survey form. To reference pre-existing data in a survey
form:

 Upload one or more .csv files as support files when you upload your form
definition (the same way you upload media support files as explained in
the Media section).The first row of each .csv file should be a header that includes
short:
o unique names for each column
o subsequent rows which should contain the data itself
Each csv file should contain at least one column that can be used to uniquely identify
each row. Such columns will be used, at survey time, to look up which row's data to pull
into the survey. For the columns that will be used for looking up rows add _key to the
end of the column name in the first row. Any columns with names ending in _key will be
indexed for faster look-ups on your survey devices. See below an example of the
columns on a .csv file:
name_key name
mango Mango
orange Orange
How to pull data from CSV
You can be able to pull data from .csv file by including one or more .csv files in your form
during the survey time. For each data field that you want to pull into your survey:

 Add a calculate field to your survey.


 Give that field a name
 Then in its calculation column, call the pulldata() function, indicating which field
to pull from which row of which .csv file.

See below for an example:

type name label calculation


calculat pulldata('fruits', 'name', 'name_key',
fruit
e 'mango')
The fruit ${fruit} pulled from
note note_fruit
csv.
surveychoicessettings
Once you have loaded .csv data into a survey field using the pulldata() function, you can
reference that field in later relevance conditions, constraints, and labels, just as you
would reference any other field that was filled in by the user.
Click on the link to see an example of a pre-loading sample form and the .csv file used
with form can be found here
Important notes on usage of pre-loaded data
 Compress a large .csv file into a .zip archive before uploading it.
 Save .csv file in UTF-8 format if pre-loaded data contains non-English fonts or
special characters this enables your Android device to render the text correctly.
 Data fields pulled from a .csv file are considered to be text strings therefore use
the int() or number() functions to convert a pre-loaded field into numeric form.
 If the .csv file contains sensitive data that you may not want to upload to the
server, upload a blank .csv file as part of your form, then replace it with the
real .csv file by hand-copying the file onto each of your devices.

Dynamic selects from pre-loaded data


If the recommended methods described in Multiple Choice from File do not meet your
requirements you can consider the method below if your data collection application
supports it.
Once your form has one or more pre-loaded .csv files, you can dynamically pull the
choice lists for select_one and select_multiple fields from those .csv files. Multiple-
choice fields with dynamic choice lists follow the same general syntax as regular, static
select_one and select_multiple fields as previously covered in the Multiple choice
questions section.

The following should be done:

 specify select_one listname or select_multiple listname in the type column


(where listname is the name of your choice list)
 specify any special appearance styles in the appearance column
 include one or more rows for your listname on the choices worksheet.
Below is an example of the survey worksheet:
type name label appearance
select_one fruits fruits Select a fruit search('fruits')
surveychoicessettings

There are three differences when the choice list should be pulled from one of your pre-
loaded .csv files:

 In the appearance column:


 Include a search() expression that specifies which .csv rows to include in the
choice list.
 If the field should use a non-default appearance style. The non-default
appearance style goes into the column first, followed by a space, then
the search() expression. [e.g., quick search()]
 On the choices worksheet:
 a row should indicate which .csv columns to use for the label and selected value.
As follows:
o list_name column: specify the name of your choice list as you normally
would.
o name column: include the name of the .csv column to use for uniquely
identifying selected choices.
o label column: include the name of the .csv column to use for labeling the
choices.
Note:
If you wish to include multiple columns in the labels, include a comma-
separated list of all columns to include. The name column will be
dynamically populated based on the column name you put there, and the
label column will be dynamically populated based on the column name(s)
you put there.
 In your choices worksheet row, you may also include a .csv column name in the
image column. If you do, the image filename to use will be pulled from the
specified .csv column.
Note:
If you refer to image files in this way, you must always upload those image files as
media file attachments when you upload your form to the server.
See below an example of the choices worksheet:
list name name label
name_ke
fruits name
y
surveychoicessettings
Click on the link to see an example of a search-and-select sample form and the .csv file
used with form can be found here.
There are a series of options to indicate which .csv rows to include in the choice list
using the search() expression, see this post for additional information on these search()
expressions.
Cascading selects
A lot of forms start out by asking the location of the respondent, with each location
selection specifying what the subsequent location choices will be (e.g., state » district »
village). Instead of adding a select_one field for each location option, you can use
cascade select. In order to use cascade selects, you will need to create
a choice_filter column in your survey worksheet and add the location attribute columns
in your choices worksheet. Check out an example XLSForm here.

External selects
If a form has selects with a large number of choices (e.g., hundreds or thousands), that
form can slow down form loading and navigation if Multiple Choice from File is used. The
best workaround to this issue is to use external selects in those data collection
applications (such as ODK Collect) that support it.

Enabling external selects is straightforward.

 Instead of select_one for the prompt type, use select_one_external.


 Instead of the choices sheet, put external choices in
the external_choices sheet.
See select_one_external form for an example that uses normal and external choices.
When an XLSForm with external choices is converted to an XForm, two files will be
produced, the XForm (e.g., form-filename.xml) with all the normal choices, and
an itemsets.csv with the external choices.
The itemsets.csv file can be uploaded to any ODK-compatible server (e.g., ODK
Aggregate) as a media file. It will be downloaded to any ODK-compatible (e.g., ODK
Collect) like any other media file and saved to the [form-filename]-media folder. Clients
like ODK Collect load media files from the SD card and so your form with a large number
of choices will now load very quickly.

Default
Adding a default field means that a question will be pre-populated with an answer when
the user first sees the question. This can help save time if the answer is one that is
commonly selected or it can serve to show the user what type of answer choice is
expected. See the example below.

type name label default


date survey_date Survey date? 2010-06-15
decima
weight Respondent's weight? (in kgs) 51.3
l
surveychoicessettings
The respondent can simply change the answer by tapping in the answer field and
entering another answer.

You can also add a default calculation, which will only be calculated only once when the
form loads or - if the question is inside a repeat - when the repeat is added.
typ
name label default
e
Enter the date the event
date d today()
occurred?
surveychoicessettings

Read only
Adding a read only field means that a question can not be edited. Read only fields can
be combined with default fields to deliver information back to a user.

nam
type label read_only default
e
integer num Please patient is: yes 5
surveychoicessettings

Appearance
The appearance column allows you to change the appearance of questions in your form.
The following table lists the possible appearance attributes and how the question
appears in the form.
Appearance
Question type Description
attribute
Best if used with web clients, makes the text box
multiline text
multiple lines long.
select_one,
minimal Answer choices appear in a pull-down menu.
select_multiple
Relevant for mobile clients only, this attribute
quick select_one auto-advances the form to the next question after
an answer is selected.
For mobile devices only, used to suppress the
no-calendar date
calendar.
month-year date Select a month and year only for the date.
year date Select only a year for the date.
horizontal- select_one, For web clients only, this displays the answer
compact select_multiple choices horizontally.
select_one, For web clients only, this displays the answer
horizontal
select_multiple choices horizontally, but in columns.
likert select_one Best if used with web clients, makes the answer
Appearance
Question type Description
attribute
choices appear as a Likert scale.
Displays answer choices side by side with
select_one, minimal padding and without radio buttons or
compact
select_multiple checkboxes. Particularly useful with image
choices.
Same as previous, but auto-advances to the next
quickcompact select_one
question (in mobile clients only).
Entire group of questions appear on one screen
field-list groups
(for mobile clients only).
select_one,
label Displays answer choice labels (and not inputs).
select_multiple
Used in conjunction with label attribute above,
displays the answer inputs without the labels
select_one,
list-nolabel (make sure to put label and list-nolabel fields
select_multiple
inside a group with field-list attribute if using
mobile client).
An easier way to achieve the same appearance
table-list groups as above, apply this attribute to the entire group
of questions (might slow down the form a bit).
Allows you to trace your signature into your form
signature image
(mobile clients only).
Allows you to sketch a drawing with your finger on
draw image
the mobile device screen.
select_one, Allows a user to select a choice from many
map, quick map
select_one_from_file features on a map
An XLSForm with all of the appearance attributes in this table is available here.

Settings worksheet
The settings worksheet is optional, but it is highly recommended to
specify form_title, form_id and version at a minimum. Other settings allow you to
further customize your form, including setting an overall style theme or encrypting your
records.
An example settings worksheet is below:
form_titl form_i default_langua public_ke
version instance_name
e d ge y
concat($
201702150
Example ex_id {firstname}, ' ', $ English (en) IIBIjANBg…
1
{lastname})
surveychoicessettings

The settings column headings available are:

 form_title: The title of the form that is shown to users. The form title is pulled
from form_id if form_title is blank or missing.
 form_id: The name used to uniquely identify the form on the server. The form id
is pulled from the XLS file name if form_id is blank or missing.
 version: String that represents this version. A common convention is to use
strings of the form 'yyyymmddrr'. For example, 2017021501 is the 1st revision
from Feb 15th, 2017.
 instance_name: Expression using form fields to identify for each form
submission. Learn more.
 default_language: In localized forms, this sets which language should be used
as the default. The same format as described for adding translations should be
used, including the language code.
 public_key: For encryption-enabled forms, this is where the public key is copied
and pasted. Learn more.
 submission_url: This url can be used to override the default server where
finalized records are submitted to. Learn more.
 style: For web forms, specify the form style. Learn more.
 name: XForms root node name. This is rarely needed, learn more.

Encrypted forms
Encryption-enabled forms provide a mechanism to keep finalized records private at all
times. This includes the time after a record is marked as final that it is stored on the
device and server as well as during transport, even when http is used for communication.
Encrypted records including their uploaded files, such as photos, are completely
inaccessible to anyone not possessing the private key.
To encrypt XLS forms, add the public_key column to the settings worksheet and paste
the base64-encoded public RSA key as its value.
form_i
public_key
d
mysurve IIBIjANBgklawWEserewrwesgdreewrwe32serfserfewrwerewtwer23sgfrqjwerk3423
y 432…
surveychoicessettings
For more information on encrypted forms and how to generate the RSA keys have a look
at the ODK documentation and at this example form.

Specify alternative server


It is possible to specify an alternative server to send your submissions to in
the submission_url column on the settings worksheet. Make sure to use the full URL
that submissions should be sent to including the path.

If this column is left out or kept empty, submissions will go the default destination for the
provider you are using for your surveys.

Specify form submission name


In the settings worksheet, you can specify a unique name for each form submission
using fields filled in by the user during the survey. On the settings worksheet, add a
column called instance_name. Write in the expression that defines the unique form
instance name using fields from the survey worksheet.
Check out this example XLSForm that calculates the instance name as the user's last
and first names coupled with the form submission uuid.

Specify XForms root node name


In some rare cases, it may be helpful to explicitly specify a root node name for the
generated XForm. For example, this may be necessary if updating a form that was
converted with an older form converter that used a root node name other than data. In
the settings worksheet, you can specify an identifier to use for the XForms root node
name by adding a collumn called name. By default, the XForms root node name is data.

Multiple webpage forms


Web forms can be split into multiple pages using the style theme pages.
An example of a form divided into multiple pages can be seen on the Widgets on
Pages webform.
In the settings tab, create a column called style and set it to pages, as follows:
form_title form_id style
example example_i
pages
title d
surveychoicessettings
In your survey tab, group together the questions you would like to appear on each page
and then set the appearance for the group to field-list. See the example below.
type name label appearance
type name label appearance
begin
group1 field-list
group
text name Respondent's name
integer age Respondent's age
text address Respondent's address
end group
surveychoicessettings
See this blog post for more information on creating multi-page web forms. The XLSForm
source is here.

Grid theme forms


The theme-grid style allows your form to mimic the look of traditional paper surveys by
compacting multiple questions into one row. This style is best used with larger screens
(e.g., computers or tablets). It also makes a nice print out!
Please click on the link to see an example of a Grid theme webform.
To create a Grid form, in the settings tab, under the style column, write theme-grid, as
follows:
form_title form_id style
example example_i
theme-grid
title d
surveychoicessettings
In your survey tab, group together the questions you would like to appear in each
section and then set the appearance for each field according to the desired width (the
default width is 4). See the example below.
type name label appearance
begin
group1
group
text name Respondent's name w3
integer age Respondent's age w1
text address Respondent's address w4
end group
surveychoicessettings
See this blog post for more information on creating Grid forms. The Grid theme XLSForm
example is here.

Styling prompts
Markdown support in XLSForm allows for increased emphasis through bold and italics,
different sized headers, various fonts and colors, and clickable web links in ODK Collect
1.4.9 and Enketo.

 emphasize words by wrapping them inside _ or *


 strongly emphasize words by wrapping them inside __ or **
 add a link by using [name of link](url)
 add various sized headers by prepending # (biggest) to ###### (smallest) to
header text
 style text for color or font with span tags (e.g., <span
style="color:#f58a1f">orange</span>, <span style="color:red; font-
family:cursive">red and cursive</span>)
 add a line break where you want it with Ctrl-Enter or Ctrl-Alt-Enter (may be
different key combination for some spreadsheet software)
 add your favorite emojis 😍📋😍!
 use superscript with the <sup> tag (e.g. 100 m<sup>2</sup> turns into 100 m2)
 use subscript with the <sub> tag (e.g. H<sub>2</sub>O turns into H2O)
 use the \ character before #, *, _, and \ to prevent special styling effects to be
triggered by these characters

Advanced use and extensibility


It is possible to use XLSForm to create XForms with custom or experimental features.
This is great for custom applications with a specific feature that is not suitable for the
larger community.

The survey sheet has support for 3 column prefixes (instance::, bind::, body::) that
add attributes to the XForm output, either in the primary instance, bind, or form control.
To learn more about XForms visit the ODK XForms Specification. The example below
adds a custom "hxl" attribute to the primary instance node of a question.
type name label instance::hxl
intege How many people
population #population
r present?
surveychoicessettings
The settings sheet has support for defining (multiple space-separated) additional
custom namespaces and namespace prefixes using the namespaces column. You'll
then be able to use those namespaces in the survey sheet, for example to properly
define a custom attribute with your organisation's own namespace. See example below
that adds 2 additional namespaces and uses them to add custom attributes:
title namespaces
My
esri="http://esri.com/xforms" enk="http://enketo.org/xforms
Form
surveychoicessettings

type name label bind::esri:fieldLength bind::enk:for


text desc Describe 50
desc_commen
text Comments ${a}
t
surveychoicessettings

Tools that support XLSForms


 Ona
 Enketo
 ODK
 KoBoToolBox
 CommCare
 SurveyCTO
 DataWinners
 Secure Data Kit (SDK)
 Tattara
 Survey123 for ArcGIS
 Community Health Toolkit

More resources
The XLSform standard document can guide you through the specific input types, column
headers, and so on that are legitimate syntax in XLSForms. If you want to dig in deeper
to understand XForms and go beyond XLSForms, here are some resources to
understand them:
 XForms as supported by the ODK ecosytem
 ODK Form design guidelines
 Ona Form design overview
 KoBoToolbox form design help center

About this site


XLSForm.org is a community-supported project aiming to create a common reference
point for the XLSForm standard.

If you want to contribute to or improve this documentation, please visit our project's
GitHub repo.

History
The XLSForm was originally developed by Andrew Marder and Alex Dorey of
the Sustainable Engineering Lab at Columbia University. As XLSForms became adopted
by the ODK Community, SEL worked with the ODK Team to develop the current
specification. PyXForm, the library used to convert XLSForms to XForms, is an open
source project supported by members of ODK, SEL, Ona, SurveyCTO, and
KoBoToolbox.
ODK XForms Specification

Introduction
Changelog
The ODK XForms specification is used by tools in the ODK ecosystem. It is a subset of the
far larger W3C XForms 1.0 specification and also contains a few additional features not found
in the W3C XForms specification.

The purpose of this specification is to provide a common form description standard that many
different kinds of compatible tools can be based on. Using a single, shared form description
standard has the following advantages:

1. Users in the ODK ecosystem can mix and match tools and reassess which they use
based on their changing needs. In particular, they don’t get locked in to tools that
may become deprecated or for which an attractive replacement becomes available.
2. Tool implementors in the ODK ecosystem can benefit from feedback from a broad
range of collaborators when designing new core functionality.
3. Tool implementors in the ODK ecosystem can share core implementations.
This document is intended primarily for developers who build form processing engines or
software form builders. Most organizations who use tools in the ODK ecosystem for data
collection will prefer to create forms using the XLSForm standard or a graphical form builder.
A version of this specification was initially developed by the OpenRosa
Consortium. JavaRosa is a Java library initially developed by the consortium as a J2ME app
that implements this specification. There are now several other compatible implementations.
The document assumes at least a fair understanding of XML and XPath. It is also useful to
refer to XForms 1.0 for details about shared features.

Structure
The high-level form definition is structured as follows:

 model
o instance
o bindings
 body
The model contains the instance(s) and the bindings. The first instance is the XML data
structure of the record that is captured with the form. A binding describes an individual
instance node and includes information such as datatype, skip logic, calculations, and more.
The body contains the information required to display a form.

Below is an example of a complete and valid XForm:


<?xml version="1.0"?>
<h:html xmlns="http://www.w3.org/2002/xforms"
xmlns:h="http://www.w3.org/1999/xhtml"
xmlns:jr="http://openrosa.org/javarosa"
xmlns:orx="http://openrosa.org/xforms"
xmlns:odk="http://www.opendatakit.org/xforms"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<h:head>
<h:title>My Survey</h:title>
<model>
<instance>
<data id="mysurvey" orx:version="2014083101">
<firstname></firstname>
<lastname></lastname>
<age></age>
<orx:meta>
<orx:instanceID/>
</orx:meta>
</data>
</instance>
<bind nodeset="/data/firstname" type="xsd:string"
required="true()" />
<bind nodeset="/data/lastname" type="xsd:string" />
<bind nodeset="/data/age" type="xsd:int" />
<bind nodeset="/data/orx:meta/orx:instanceID"
preload="uid" type="xsd:string"/>
</model>
</h:head>
<h:body>
<input ref="/data/firstname">
<label>What is your first name?</label>
</input>
<input ref="/data/lastname">
<label>What is your last name?</label>
</input>
<input ref="/data/age">
<label>What is your age?</label>
</input>
</h:body>
</h:html>

Outside of this simplified structure there are ways to define:

 form title as the <title> element, a child of the <head> element in the same
“http://www.w3.org/1999/xhtml” namespace,
 linkages with external (mobile) applications,
 language dictionaries.

Namespaces
XML namespaces provide a way to avoid name conflicts for element and attribute names. In
ODK XForms, the elements and attributes that are also in XForms 1.0 are in the XForms
namespace which is declared as the default namespace in the example above
( xmlns="http://www.w3.org/2002/xforms" ). Setting a default namespace means
that non-prefixed elements and attributes are assigned that namespace.
Elements and attributes that are specific to ODK XForms and not defined by the XForms 1.0
specification should be separately namespaced. For historical reasons,
the "http://openrosa.org/javarosa" namespace (with the jr prefix in this
document), and the "http://openrosa.org/xforms" namespace (with the orx prefix
in this document) have been used.
For any new additions not defined in another specification,
the "http://www.opendatakit.org/xforms" namespace is now preferred. It is
assigned the odk prefix in this documentation. If a new feature is copied from another
XForms implementation the originator’s namespace will be used.
For more information about namespaces, see the XML Namespaces specification.

Instance
A <model> can have multiple instances as childnodes. The first and
required <instance> is called the primary instance and represents the data structure of the
record that will be created and submitted with the form. Additional instances are
called secondary instances.

Primary Instance
The primary instance is the first instance defined by the form and should contain a single
childnode. In the example below <household> will be populated with data and submitted.
The primary instance’s single child is the document root that XPath expressions are
evaluated on (e.g. in the instance below the value of /household/person/age is 10).
<instance>
<household id="mysurvey" orx:version="2014083101">
<person>
<firstname/>
<lastname/>
<age>10</age>
</person>
<meta>
<instanceID/>
</meta>
</household>
</instance>
Any value inside a primary instance is considered a default value for that question. If that
node has a corresponding input element that value will be displayed to the user when the
question is rendered. For nodes of type “binary”, defaults use file endpoint URIs.
Nodes inside a primary instance can contain attributes. The client application normally retains
the attribute when a record is submitted. There are 3 pre-defined instance attributes:

attribute description

id on the childnode of the primary instance: This is the unique ID at


which the form is identified by the server that publishes the Form
and receives data submissions. For more information see the
OpenRosa Form List API. [required]

orx:version on the childnode of the primary instance in


the http://openrosa.org/xforms/ namespace: Form version which can
contain any string value. Like meta nodes this information is used as
a processing cue for the server receiving the submission.

odk:prefix on the childnode of the primary instance in


the http://opendatakit.org/xforms namespace: optional string prefix
which is included at the beginning of the compact representation

odk:delimiter on the childnode of the primary instance in


the http://opendatakit.org/xforms namespace: optional string
delimiter which is used to separate prefix, tags and values in
the compact representation

odk:tag on a question node (grandchild of the primary instance) in


the http://opendatakit.org/xforms namespace: optional string tag
which is used to identify nodes that should be part of the compact
representation

jr:template on any repeat group node in the http://openrosa.org/javarosa


namespace: This serves to define a default template for repeats and
is useful if any of the leaf nodes inside a repeat contains a default
value. It is not transmitted in the record and only affects the
behavior of the form engine. For more details, see
the repeats section.
The primary instance also includes a special type of nodes for metadata inside
the <meta> block. See the Metadata section

Secondary Instances - Internal


Secondary instances are used to pre-load read-only data inside a form. This data is searchable
in XPath. At the moment the key use case is in designing so-called cascading
selections where the available options of a multiple-choice question can be filtered based on
an earlier answer.
A secondary instance should get a unique id attribute on the <instance> node. This
allows apps to query the data (which is outside the root, ie. the primary instance, and would
normally not be reachable). It uses
the instance('cities')/root/item[country='nl'] syntax to do this.
<instance>
<household id="mysurvey" version="2014083101">
<person>
<firstname/>
<lastname/>
<age>10</age>
</person>
<meta>
<instanceID/>
</meta>
</household>
</instance>
<instance id="cities">
<root>
<item>
<itextId>static_instance-cities-0</itextId>
<country>nl</country>
<name>ams</name>
</item>
<item>
<itextId>static_instance-cities-1</itextId>
<country>usa</country>
<name>den</name>
</item>
<item>
<itextId>static_instance-cities-2</itextId>
<country>usa</country>
<name>nyc</name>
</item>
<item>
<itextId>static_instance-cities-5</itextId>
<country>nl</country>
<name>dro</name>
</item>
</root>
</instance>
<instance id="neighborhoods">
<root>
<item>
<itextId>static_instance-neighborhoods-0</itextId>
<city>nyc</city>
<country>usa</country>
<name>bronx</name>
</item>
<item>
<itextId>static_instance-neighborhoods-3</itextId>
<city>ams</city>
<country>nl</country>
<name>wes</name>
</item>
<item>
<itextId>static_instance-neighborhoods-4</itextId>
<city>den</city>
<country>usa</country>
<name>goldentriangle</name>
</item>
<item>
<itextId>static_instance-neighborhoods-8</itextId>
<city>dro</city>
<country>nl</country>
<name>haven</name>
</item>
</root>
</instance>

Secondary Instances - External


The previous section discussed secondary instances with static read-only data that is present
in the XForm document itself. Another type of secondary instances presents read-only data
from an external source. The external source can be static or dynamic and is specified using
the additional src attribute with a URI value on an empty <instance> node. Querying an
external instance is done in exactly the same way as for an internal secondary instance.
<instance id="countries" src="jr://file/country-data.xml"/>
See the section on URIs for acceptable URI formats that refer to an external secondary
instance.

Bindings
A <bind> element wires together a primary instance node and the presentation of the
corresponding question to the user. It is used to describe the datatype and various kinds of
logic related to the data. A bind can refer to any node in the primary instance including
repeated nodes. It may or may not have a corresponding presentation node in the body.
An instance node does not require a corresponding <bind> node, regardless of whether it
has a presentation node.
<bind nodeset="/d/my_intro" type="string" readonly="true()"/>
<bind nodeset="/d/text_widgets/my_string" type="string"/>
<bind nodeset="/d/text_widgets/my_long_text" type="string"/>
<bind nodeset="/d/number_widgets/my_int" type="int" constraint=".
&lt; 10" jr:constraintMsg="number must be less than 10" />
<bind nodeset="/d/number_widgets/my_decimal" type="decimal"
constraint=". &gt; 10.51 and . &lt; 18.39"
jr:constraintMsg="number must be between 10.51 and 18.39" />
<bind nodeset="/d/dt/my_date" type="date" constraint=". &gt;=
today()" jr:constraintMsg="only future dates allowed" />
<bind nodeset="/d/dt/my_time" type="time"/>
<bind nodeset="/d/dt/dateTime" type="dateTime"/>
<bind nodeset="/d/s/my_select" type="select"
constraint="selected(., 'c') and selected(., 'd'))"
jr:constraintMsg="option c and d cannot be selected together" />
<bind nodeset="/d/s/my_select1" type="select1"/>
<bind nodeset="/d/geo/my_geopoint" type="geopoint"/>
<bind nodeset="/d/geo/my_geotrace" type="geotrace"/>
<bind nodeset="/d/geo/my_geoshape" type="geoshape"/>
<bind nodeset="/d/media/my_image" type="binary"/>
<bind nodeset="/d/media/my_audio" type="binary"/>
<bind nodeset="/d/media/my_video" type="binary"/>
<bind nodeset="/d/media/my_barcode" type="barcode"/>
<bind nodeset="/d/display/my_trigger" required="true()"/>

Bind Attributes
The following attributes are supported on <bind> nodes. Only the nodeset attribute is
required.
attribute description

nodeset As in XForms 1.0 this specifies the path to the instance node or
attribute [required].

type As in XForms 1.0 this specifies the data type. These data
types values are supported and is considered “string” if omitted
or if an unknown type is provided.

readonly As in XForms 1.0 this specifies whether the user is allowed to


enter data, using a boolean expression. Considered false() if
omitted.

required As in XForms 1.0 this pecifies whether the question requires a


non-empty value, using a boolean expression.
Considered false() if omitted.

relevant As in XForms 1.0 this specifies whether the question or group is


relevant. The question or group will only be presented to the
user when the XPath expression evaluates to true() .
When false() the data node (and its descendants) are
removed from the primary instance on submission.

constraint As in XForms 1.0 this specifies acceptable answers for the


specified prompt with an XPath expression. Will only be
evaluated when the node is non-empty.

calculate As in Xforms 1.0 this calculates a node value with an XPath


attribute description

expression.

saveIncomplete Specifies whether to automatically save the draft record when


the user reaches this question, options true() and false() .
Considered false() if omitted.

jr:requiredMsg Specifies the custom message to be displayed when


the required is violated. Value can be string literal
( jr:constraintMsg="message" ) or a translation
function call ( jr:constraintMsg="jr:itext('id')" ).

jr:constraintMsg Specifies the custom message to be displayed when


the constraint is violated. Value can be string literal
( jr:requiredMsg="message" ) or a translation
function call ( jr:requiredMsg="jr:itext('id')" ).

jr:preload Preloaders for predefined meta data. See preload attributes.

jr:preloadParams Parameters used by jr:preload . See preload attributes.

orx:max-pixels Specifies a transformation for uploaded images (binary


datatype), e.g. orx:max-pixels="1024" . If the long edge
of the image is larger than the provided number value, the
image should be resized proportionally so that the long edge
matches the provided pixel value.

Data Types
The following are acceptable data type values.

type description

string As in XML 1.0, optionally in “http://www.w3.org/2001/XMLSchema”


namespace

int As in XML 1.0, optionally in “http://www.w3.org/2001/XMLSchema”


namespace

boolean As in XML 1.0, optionally in “http://www.w3.org/2001/XMLSchema”


namespace

decimal As in XML 1.0, optionally in “http://www.w3.org/2001/XMLSchema”


type description

namespace

date As in XML 1.0, optionally in “http://www.w3.org/2001/XMLSchema”


namespace

time As in XML 1.0, optionally in “http://www.w3.org/2001/XMLSchema”


namespace

dateTime Deviates from XML 1.0, in that it includes the timezone offset (i.e. not
normalized to UTC). The timezone offset is HH:MM, where both hours and
minutes are required and are zero-padded, preceded by the + or - sign
without any spaces. The offset may also equal “Z”.

geopoint Space-separated list of valid latitude (decimal degrees), longitude (decimal


degrees), altitude (decimal meters) and accuracy (decimal meters)

geotrace Semi-colon-separated list of at least 2 geopoints, where the last geopoint’s


latitude and longitude is not equal to the first

geoshape Semi-colon-separated list of at least 3 geopoints, where the last geopoint’s


latitude and longitude is equal to the first

binary URI pointing to binary file. For user-uploaded files attached to a


submission, only the filename with extension should be used without a
scheme or subdirectories.

barcode As string

intent As string, used for external applications

XPath Paths
XPath paths are used in XForms to reference instance nodes to store or retrieve data. Both
absolute and relative paths are supported, along with using the proper relative path context
node, depending on the situation. Paths can currently only reference XML elements (not
attributes, comments, or raw text). The references . and .. are also supported at any point
in the path.

The following are examples of valid paths:

 .
 ..
 /
 node
 /absolute/path/to/node
 ../relative/path/to/node
 ./relative/path/to/node
 another/relative/path
 //node

XPath Operators
All XPath 1.0 operators are supported, i.e. | , and , or , mod , div , = , !
= , <= , < , >= , > , + , - .
Note that the standard XPath type conversions are extended by this specification in
the number() function. This extended functionality provides the ability to perform
arithmetic with, and compare, date and dateTime strings.

XPath Predicates
Predicates are fully supported but with the limitations described in XPath Axes and XPath
Functions

XPath Axes
Only the parent, child and self axes are supported of the XPath 1.0 axes.

XPath Functions
A subset of XPath 1.0 functions, XForms functions, some functions of later versions of
XPath, and a number of additional custom functions are supported. Some of the
XPath/XForms functions have been extended with additional functionality.
The XPath evaluator will automatically cast function arguments to their required data types by
calling the number() , string() , boolean() functions, as described in XPath 1.0. The
XPath evaluator has no knowledge of the data type of the value stored in the model. In
XForms, node values are always stored and obtained as strings.
Note: since expression results are stored in the XForms model as strings using
the string() function, a boolean false result, such as from the expression 1 > 2 , is
stored in the model as the string "false" . When referring to that node in another
expression as a boolean argument, the string value of that node (“false”) is converted to a
boolean by calling the boolean() function which returns the
boolean true because boolean("false") = true() . To deal with this, it usually
best to not do boolean comparisons with stored values (compare strings instead) or
use boolean-from-string() in the XPath comparison expression.
The table below describes the functions, and the data types of their arguments and return
values, using the following special argument characters:

 ? argument is optional
 * argument can be repeated
 | alternative argument is allowed

For convenience, the functions are categorized based on their main usage. Some functions
could be argued to (also) belong in another category. However, the data type rules mentioned
above are the same for all functions, regardless of the category they have been placed under.

function retu description


rns

String
Functions

string(* strin As in XPath 1.0.


arg) g

concat(str strin Deviates from XPath 1.0 in that it may contain 1 argument and
ing arg*| g that all arguments can be node-sets or strings. It concatenates all
node-set string values and all node values inside the provided node-sets.
arg*)

join(strin strin Joins the provided arguments using the provide separator
g g between values.
separator,
node-set
nodes*)

substr(str strin Returns the substring beginning at the specified 0-based start
ing value, g index and extends to the character at end index - 1.
number
start,
number
end?)

substring- strin As in XPath 1.0.


before(str g
ing,
string)

substring- strin As in XPath 1.0.


function retu description
rns

after(stri g
ng,
string)

translate( strin As in XPath 1.0.


string, g
string,
string)

string- num Deviates from XPath 1.0 in that the argument is required.
length(str ber
ing arg)

normalize- strin As in XPath 1.0


space(stri g
ng arg?)

contains(s bool As in XPath 1.0.


tring ean
haystack,
string
needle)

starts- bool As in XPath 1.0.


with(strin ean
g
haystack,
string
needle)

ends- bool As in XPath 3.0.


with(strin ean
g
haystack,
string
needle)

uuid(numbe strin Without arguments, it returns a random RFC 4122 version


r?) g 4 compliant UUID. With an argument it returns a random string
function retu description
rns

with the provided number of characters.

digest(str strin As in XForms 1.1


ing src, g
string
algorithm,
string
encoding?)

pulldata(s strin Returns a single value from a secondary instance based on the
tring g specified query. Shortcut
instance_i for instance(instance_id)/root/item[query_ele
d, string ment=query]/desired_element .
desired_el
ement,
string
query_elem
ent,
string
query)

Boolean
Functions

if(boolean strin Deviates from XForms 1.0 in that the 2nd and 3rd parameter are
condition, g objects and not strings.
* then, *
else)

coalesce(s strin Returns first non-empty value of arg1 and arg2 or empty if both
tring g are empty and/or non-existent.
arg1,
string
arg2)

once(strin strin The parameter will be evaluated and returned if the context
g calc) g nodes’s value is empty, otherwise the current value of the
context node will be returned. The function is used e.g. to
ensure that a random number is only generated once
with once(random()) .
function retu description
rns

true() bool As in XPath 1.0.


ean

false() bool As in XPath 1.0.


ean

boolean(* bool As in XPath 1.0.


arg) ean

boolean- bool Deviates from XForms 1.0 in that it returns false for any
from- ean argument that is not “true” or “1”.
string(str
ing arg)

not(boolea bool As in XPath 1.0.


n arg) ean

regex(stri bool Returns result of regex test on provided value. The regular
ng value, ean expression is created from the provided expression string
string ( '[0-9]+' becomes /[0-9]+/ ).
expression
)

checklist( bool Check whether the count of answers that evaluate to true (when
number ean it converts to a number > 0) is between the minimum and
min, maximum inclusive. Min and max can be -1 to indicate not
applicable.
number
max,
string v*)

weighted- bool Like checklist(), but the number of arguments has to be even.
checklist( ean Each v argument is paired with a w argument that weights each
number v (true) count. The min and max refer to the weighted totals.
min,
number
max,
[string v,
string
w]*)
function retu description
rns

Number
Functions

number(* num As in XPath 1.0. In addition it will convert date- and dateTime-
arg) ber formatted strings to a number of days since January 1, 1970
UTC.

random() num Deviates from XForms 1.1 by not supporting a parameter.


ber

int(number num Converts to an integer (a whole number) by discarding the


arg) ber fractional component of a number.

sum(node- num As in XPath 1.0.


set arg) ber

max(node- num As in XPath 3.0.


set arg*) ber

min(node- num As in XPath 3.0.


set arg*) ber

round(numb num Deviates from XPath 1.0 in that a second argument may be
er arg, ber provided to specify the number of decimals.
number
decimals?)

pow(number num As in XPath 3.0.


value, ber
number
power)

log(number num As in XPath 3.0.


arg) ber

log10(numb num As in XPath 3.0.


er arg) ber

abs(number num As in XPath 3.0.


arg) ber
function retu description
rns

sin(number num As in XPath 3.0.


arg) ber

cos(number num As in XPath 3.0.


arg) ber

tan(number num As in XPath 3.0.


arg) ber

asin(numbe num As in XPath 3.0.


r arg) ber

acos(numbe num As in XPath 3.0.


r arg) ber

atan(numbe num As in XPath 3.0.


r arg) ber

atan2(numb num As in XPath 3.0.


er arg, ber
number
arg)

sqrt(numbe num As in XPath 3.0.


r arg) ber

exp(number num As in XPath 3.0.


arg) ber

exp10(numb num As in XPath 3.0.


er arg) ber

pi() num As in XPath 3.0.


ber

Node-set
Functions

count(node num As in XPath 1.0.


-set arg) ber
function retu description
rns

count-non- num As in XForms 1.0.


empty(node ber
-set arg)

position(n num Deviates from XPath 1.0 in that it accepts an argument. This
ode arg?) ber argument has to be a single node. If an argument is provided the
function returns the position of that node amongst its siblings
(with the same node name).

instance(s node As in XForms 1.0. Note that it doesn’t switch the document root
tring id) -set for predicates. E.g.
in instance('cities')/item/[country=/data/cou
ntry] , the /data/country path still refers to the primary
instance.

current() node As in XForms 1.1. Used inside predicates of expressions that


-set use instance() to enable referring to a node relative to the
context of the current question. E.g. as
in instance('countries')/item[name=current()/
../name]/capital ).

randomize( node Shuffles the node-set argument using the “inside-out” variant of
node-set -set the Fisher-Yates algorithm. The optional seed argument
arg, performs a (reproducible) shuffle using the same algorithm with
a seeded Park Miller Pseudo Number Generator.
number
seed)

Date and
Time
Functions

today() strin Returns a string with today’s local date in the format described
g under the date datatype.

now() strin Deviates from XForms 1.0 in that it returns the current date and
g time including timezone offset (i.e. not normalized to UTC) as
described under the dateTime datatype.

format- strin Returns the provided date value formatted as defined by the
date(date g format argument using the following identifiers:
value, %Y : 4-digit year
string %y : 2-digit year
function retu description
rns

format) %m 0-padded month


%n numeric month
%b short text month (Jan, Feb, etc)*
%d 0-padded day of month
%e day of month
%a short text day (Sun, Mon, etc).*
* If form locale can be determined that locale will be used. If
form locale cannot be determined the locale of the client will be
used (e.g. the browser or app).

format- strin Returns the provided dateTime value formatted as defined by


date- g the format argument using the same identifiers as format-
time(dateT date plus the following:
ime value, %H 0-padded hour (24-hr time)
string %h hour (24-hr time)
format) %M 0-padded minute
%S 0-padded second
%3 0-padded millisecond ticks.*
* If form locale can be determined that locale will be used. If
form locale cannot be determined the locale of the client will be
used (e.g. the browser or app).

date(* strin Converts to a string in the ….date format.


value) g

decimal- num Converts dateTime value to the number of days since January 1,
date- ber 1970 UTC.
time(dateT
ime value)

decimal- num Converts time value to a number representing a fractional day in


time(time ber the device’s timezone. For example, noon is 0.5 and 6pm is
value) 0.75.

Select
Functions

selected(s bool Checks if value is equal to an item in a space-separated list


tring ean (e.g. select data type values).
list,
function retu description
rns

string
value)

selected- strin Returns the value of the item at the 0-based index of a space-
at(string g separated list or empty string if the item does not exist
list, (including for negative index and index 0).
number
index)

count- num Returns the number of items in a space-separated list


selected(n ber (e.g. select data type values).
ode node)

jr:choice- strin Returns the label value in the active language corresponding to
name(node g the choice option with the given value of a select or select1
node, question for the given data node. (sorry)
string
value)

Translation
Functions

jr:itext(s strin Obtains an itext value for the provided reference in the active
tring id) g language from the <itext> block in the model.

Repeat
Functions

indexed- strin Returns a single node value from a node-set by selecting the 1-
repeat(nod g based index of a repeat node-set that this node is a child of. It
e-set arg, does this up to 3 repeat levels deep. E.g. indexed-
node-set repeat(//node, /path/to/repeat, //index1,
repeat1, /path/to/repeat/nested-repeat, //index2) is
number meant to be a shortcut
for //repeat[position()=//index1]/nested-
index1,
repeat[position()=index2]/node in native XPath
[node-set
syntax.
repeatN,
number
indexN]
{0,2})
function retu description
rns

Geographic
Functions

area(node- num Returns the calculated area in m2 of either a node-set of


set ns| ber geopoints or a geoshape value (not a combination of both) on
geoshape Earth. It takes into account the circumference of the Earth
around the Equator but does not take altitude into account.
gs)

distance(n num Returns the distance in meters of either a node-set of geopoints


ode-set ber or a single geoshape value or a single geotrace value (not a
ns| combination of these) on Earth, in the sequence provided by the
points in the parameter. It takes into account the circumference
geoshape of the Earth around the Equator and does not take altitude into
gs| account.
geotrace
gt)

Metadata
This section describes metadata about the record that is created with the form. Metadata
about the form itself (id, version, etc) is covered in the Primary Instance section.

The namespace of the meta block is either the default XForms namespace or
“https://openrosa.org/xforms”. The latter is recommended.

<instance>
<data id="myform" orx:version="637">
<question2/>
<casename/>
<confirm/>
<orx:meta>
<orx:deviceID/>
<orx:timeStart/>
<orx:timeEnd/>
<orx:userID/>
<orx:instanceID/>
<orx:audit/>>
</orx:meta>
</data>
</instance>
These meta elements have corresponding <bind> elements with either a calculation or
with preload attributes. Note that when using a calculation these values may be recalculated,
e.g. when a draft record is loaded. This could lead to undesirable results for example when the
result is a random value or timestamp.

Using both a calculation and preload attributes is technically allowed but never recommended,
because one will overwrite the other.

The following meta elements are supported:

element description default value namespac


datatyp e
e

instanceID The unique ID of the record string concatenatio same as


[required] n of ‘uuid:’ meta
and uuid() block

timeStart A timestamp of when the form datetim now() same as


entry was started e meta
block

timeEnd A timestamp of when the form datetim now() same as


entry ended e meta
block

userID The username stored in the string same as


client, when available meta
block

deviceID Unique identifier of client string depends on same as


install. Guaranteed not to be client, meta
blank. For privacy reasons, prefixed block
this identifier should be stored
as application state and be
user-resettable (e.g. by
reinstalling the client or
clearing cookies). Clients
typically use a prefix to
identify themselves
(e.g. enketo.org:SOMEID
).

deprecated The <instanceID/> of the string same as


ID submission for which this is a meta
revision. This revision will get block
a newly
generated <instanceID/>
and this field is populated by
the prior value. Server
element description default value namespac
datatyp e
e

software can use this field to


unify multiple revisions to a
submission into a consolidated
submission record.

email The user’s email address when string same as


available. meta
block

phoneNumbe The phone number of the string same as


r device, when available meta
block

audit A CSV or zipped CSV file binary filename same as


containing audit logs meta
pertaining to the record (e.g., block
timing, location). The file is
attached in the same way as
for an <upload> form
control and binary instance
node. Filename is determined
by the client and file follows
this documented format. What
data is recorded is
configurable via audit
attributes.

Preload Attributes
As mentioned in Bind Attributes, there are two different preload attributes. A particular
combination of pre-load attributes populates a value according to a predetermined fixed
formula, when a predetermined event occurs. Different combinations handle different
events and use a different calculation.

Supported preload attribute combinations are:

jr:preloa jr:preloadParams value event


d

uid see instanceID odk-instance-first-load

timestamp start see timeEnd odk-instance-first-load


jr:preloa jr:preloadParams value event
d

timestamp end see timeEnd xforms-revalidate

property deviceid see deviceID odk-instance-first-load

property email see email odk-instance-first-load

property username see userID odk-instance-first-load

property phone number see phoneNumber odk-instance-first-load

Audit Attributes

attribute description

odk:location- no-power , low-power , balanced , or high-


priority accuracy as defined in LocationRequest. Required to enable
location in log.

odk:location- The desired minimum time, in seconds, location updates will be


min-interval fetched. Required to enable location in log.

odk:location- The maximum time, in seconds, locations will be considered


max-age valid. Must be greater than or equal to odk:location-min-
interval . Required to enable location in log.

odk:track- Can be set to "true" or "false" . If true, whenever an


changes answer is changed, the old value and new value will be added to
the log. Attribute is not required and defaults to false.

Body
The <body> contains the information required to display a question to a user, including the
type of prompt, the appearance of the prompt (widget), the labels, the hints and the choice
options.
<h:body>
<input ref="/data/firstname">
<label>What is your first name?</label>
</input>
<input ref="/data/lastname">
<label>What is your last name?</label>
</input>
<input ref="/data/age">
<label>What is your age?</label>
</input>
</h:body>

Body Elements
The following form control elements are supported:

control description

<input> This element is used to obtain user input for data types: string, integer,
decimal, and date. As in XForms 1.0 without Special Attributes support.

<select1> Used to display a single-select list (data type: string). As in XForms


1.0 without Special Attributes support.

<select> Used to display a multiple-select list (data type: string). As in XForms


1.0 without Special Attributes support.

<upload> Used for image, audio, and video capture. As in XForms 1.0 without
support for filename and mediatype child elements, nor
the incremental attribute and only supporting the binary data
type.

<trigger> Used to obtain user confirmation (e.g. by displaying a single tickbox or


button). Will add value “OK” to corresponding instance node when user
confirms. If not confirmed the value remains empty.

<range> Used to obtain numeric user input from a sequential range of values.
Mostly as in XForms 1.0. However, it does not support
the incremental attribute, and the step , start ,
and end attributes are required.

<odk:rank> Used to require user to rank/order options. The ordered options are
recorded as a space-separated list (as with <select> ). The recorded
list always includes all options.

The following user interface elements are supported:


element description

<group> Child of <body> , another <group> , or a <repeat> that groups form


controls together. See groups section for further details. As in XForms 1.0.

<repeat> Child of <body> or <group> that can be repeated. See repeats for
further details.

Within the form controls the following elements can be used:

element description

<label> Child of a form


control element, <item> , <itemset> or <group> used to display a
label. Only 1 <label> per form control is properly supported but can be
used in multiple languages). As in XForms 1.0 without support for
Linking Attributes.

<hint> Child of a form control element used to display a hint. Only


1 <hint> element per form control is properly supported but can be
used in multiple languages). As in XForms 1.0 without support for
Linking Attributes.

<output> Child of a <label> or <hint> element used to display an instance


value, inline, as part of the label, or hint text. It can also be a child of
a <text> translation. As in XForms 1.0 but only supporting
the value attribute.

<item> Child of <select> or <select1> or <odk:rank> that defines an


choice option. As in XForms 1.0.

<itemset> Child of <select> or <select1> or <odk:rank> that defines a list


of choice options to be obtained elsewhere (from a secondary instance).
As in XForms 1.0.

<value> Child of <item> or <itemset> that defines a choice value. As


in XForms 1.0.

Below is an example of a label, an output, a hint, an itemset and value used together to define
a form control:

<group ref="/data/loc">
<label>Cities</label>
...
<odk:rank ref="/data/loc/cities">
<label>Rank these cities</label>
<hint>Rank the cities in <output
value="/data/loc/country"/> in order of importance with the most
important at the top.</hint>
<itemset
nodeset="randomize(instance('cities')/root/item[country=
/data/loc/country ])">
<value ref="name"/>
<label ref="label"/>
</itemset>
</odk:rank>
</group>

Body Attributes
The following attributes are supported on body elements. Note that most attributes can only
be used on specific elements. If such a specific attribute is used on elements that do not
support it, it will usually be silently ignored.

attribute description

ref / nodeset To link a body element with its corresponding data node and
binding, both nodeset and ref attributes can be used. The
convention that is helpful is the one used in XLSForms:
use nodeset="/some/path" for <repeat> and <itemse
t> elements and use ref="/some/path" for everything else.
The ref attribute can also refer to an itext reference
(see languages)

class Equivalent to class in HTML and allows a list of space-separated


css classes as value. This attribute is only supported on
the <h:body> element for form-wide style classes.

appearance For all form control elements and groups to change their
appearance. See appearances

jr:count For the <repeat> element (see repeats). This is one of the ways
to specify how many repeats should be created by default.

jr:noAddRemove For the <repeat> element (see repeats). This indicates whether
the user is allowed to add or remove repeats. Can have
values true() and false()

autoplay For all form control elements, this automatically plays a video or
audio ‘label’ if the question is displayed on its own page, when
attribute description

the user reaches this page.

accuracyThresh For <input> with type geopoint , geotrace ,


old or geoshape this sets the auto-accept threshold in meters for
geopoint captures. review

value For the <output> element to reference the node value to be


displayed.

rows Specifies the minimum number of rows a string <input> field


gets.

mediatype For the <upload> element. The string value specifies the kind
of media picker that will be displayed. Unlike in XForms 1.0, only
one value can be specified. Possible values vary by client and
examples include image/* , audio/* and video/* . Ignored
if accept is also specified.

accept For the <upload> element. As from the XForms 2.0 wiki:
“comma-separated list of suggested media types and file
extensions used to determine the possible sources of data to
upload.”

start For the <range> element. The lower bound of the range. This
attribute is required and its value has to be valid for the data type
used.

end For the <range> element. The upper bound of the range. This
attribute is required and its value has to be valid for the data type
used.

step For the <range> element. The increment between values that
can be selected. This attribute is required and its value has to be
valid for the data type used.

Appearances
The appearance of all form controls and of a group can be changed with appearance attributes.
Appearance values usually relate to a specific data or question type. See the XLS Form
specification for a list of appearance attributes that are available for each data type. Multiple
space-separated appearance values can be added to a form control in any order.
An appearance value may also work in conjunction with an image label to substantially alter
the appearance and behavior of a form control as is e.g. the case with appearance ‘image-
map’.
An appearance attribute can also be used to indicate that an external app should be used as a
form control.

Groups
A <group> combines elements together. If it has a child <label> element, the group is
considered a presentation group and will be displayed as a visually distinct group.
A <group> may or may not contain a ref attribute. If it does, the group is considered
a logical group. A logical group has a corresponding element in the primary instance and
usually a corresponding <bind> element. A logical group’s ref is used as the context node
for the relative ref paths of its descendants.

A group can be both a logical and a presentation group.

Groups may be nested to provide different levels of structure.

Apart from providing structure, a logical group can also contain a relevant attribute on
its <bind> element, offering a powerful way to keep form logic maintainable (see bind
attributes).

The sample below includes both the body and corresponding instance. The respondent group
is a logical group and the context group is both a logical and a presentation group. The
context group will only be shown if both first name and last name are filled in.

<h:head>
<h:title>My Survey</h:title>
<model>
<instance>
<data id="mysurvey">
<respondent>
<firstname/>
<lastname/>
<age/>
</respondent>
<context>
<location/>
<township/>
<population/>
</context>
<meta>
<instanceID/>
</meta>
</data>
</instance>
....
<bind nodeset="/data/context"
relevant="string-length(../respondent/firstname) >
0 and
string-length(../respondent/lastname) > 0" />
....
</model>
</h:head>
<h:body>
<group ref="/data/respondent">
<input ref="firstname">
<label>What is your first name?</label>
</input>
<input ref="lastname">
<label>What is your last name?</label>
</input>
<input ref="age">
<label>What is your age?</label>
</input>
</group>
<group ref="/data/context">
<label>Context</label>
<input ref="location">
<label>Record the location</label>
</input>
<input ref="township">
<label>What is the name of the township</label>
</input>
<input ref="population">
<label>What is the estimated population size</label>
</input>
</group>
</h:body>

Repeats
Repeats are sections that may be repeated in a form. They could consist of a single question or
multiple questions. It is recommended to wrap a <repeat> inside a <group> though
strictly speaking not required.
A <repeat> uses the nodeset attribute to identify which instance node (and its children) can
be repeated.
A <repeat> cannot have a label child element. To display a label it should be wrapped
inside a <group> as shown below:
...
<h:head>
<h:title>A Survey with repeats</h:title>
<model>
<instance>
<data id="repeats" version="2014083101">
<person>
<name />
<relationship />
</person>
<meta>
<instanceID/>
</meta>
</data>
</instance>
...
</model>
</h:head>
<h:body>
<group ref="/data/person">
<label>Person</label>
<repeat nodeset="/data/person">
<input ref="/data/person/name">
<label>Enter name</label>
</input>
<input ref="/data/person/relationship">
<label>Enter relationship</label>
</input>
</repeat>
</group>
</h:body>
...

When a client needs to compactly show a single repeat instance in its user interface (e.g. as a
collapsed repeat or a table-of-contents item), it is recommended to show the label of the first
child group of that repeat.

Creation, Removal of Repeats


The default behavior of repeats is to let the user create or remove repeats using the user
interface. The user control for creating and removing repeats can be disabled by adding the
attribute jr:noAddRemove="true()" to the <repeat> element.

There are 2 different ways to ensure that multiple repeats are automatically created when a
form loads.

A. Multiple nodes can be defined in the primary instance of the XForm. E.g. see below for an
instance that will automatically create 3 repeats for the above form.

...
<instance>
<data id="repeats" version="2014083101">
<person>
<name />
<relationship />
</person>
<person>
<name />
<relationship />
</person>
<person>
<name />
<relationship />
</person>
<meta>
<instanceID/>
</meta>
</data>
</instance>
...
B. Using the jr:count attribute on the <repeat> element. E.g. see below for the use of
jr:count to automatically create 3 repeats for the above form. The value could also be
a /path/to/node and clients should evaluate the number of repeats dynamically.
...
<h:body>
<group ref="/data/person">
<label>Person</label>
<repeat nodeset="/data/person" jr:count="3">
<input ref="/data/person/name">
<label>Enter name</label>
</input>
<input ref="/data/person/relationship">
<label>Enter relationship</label>
</input>
</repeat>
</group>
</h:body>
...

Default Values in Repeats


There are two different ways to provide default values to elements inside repeats.

A. Specify the values inside a repeat group with a jr:template="" attribute in the
primary instance. Any new repeat that does not yet exist in the primary instance will get these
default values. The repeat group with the jr:template attribute is not part of the record
itself. So in the example below is for a form in which only a single repeat was created for
John.
...
<instance>
<data id="repeats" version="2014083101">
<person jr:template="" >
<name />
<relationship>spouse</relationship>
</person>
<person>
<name>John</name>
<relationship>father</relationship>
</person>
<meta>
<instanceID/>
</meta>
</data>
</instance>
...

B. Specify the values for each repeat instance individually in the primary instance. In the
example below the form will be loaded with 2 repeats with the values for John and Kofi.

...
<instance>
<data id="repeats" version="2014083101">
<person>
<name>John</name>
<relationship>father</relationship>
</person>
<person>
<name>Kofi</name>
<relationship>brother</relationship>
</person>
<meta>
<instanceID/>
</meta>
</data>
</instance>
...

Events and Actions


XForm Events are dispatched following different steps in the form lifecycle. XForms Actions
can be invoked in response to these events. This makes it possible to define exactly when
certain tasks should occur.

Events
See the W3C XForms specification section on events. The following events are supported:
event description

odk-instance- dispatched the first time an instance is loaded


first-load

xforms-value- As in XForms 1.1.


changed

odk-new-repeat dispatched when a new instance of a repeat is added to the


primary instance. See more.
Note: xforms-ready was previously documented as the event dispatched the first time an
instance is loaded. Since that definition does not match the W3C XForms event with the same
name, it was deprecated in favor of odk-instance-first-load .

Actions
The following subset of actions defined by the W3C XForms specification are supported:
action description

setvalue Explicitly sets the value of the specified instance data node.
See the W3C description. ref can be used in place of bind to
specify a node path instead of a node id.

odk:setgeopoint Sets the current location’s geopoint value in the instance data
node specified in the ref attribute. Any value attribute or
textContent will be ignored. Failure to retrieve the location will
result in an empty string value.
Action elements triggered by initialization events go in the model as siblings of bind nodes.
Action elements triggered by control-specific events are nested in that control block. Multiple
triggering events may be specified as a space-separated list and in that case, initialization
events may be specified in an action element nested in a control block. For example, the
value odk-instance-first-load odk-new-repeat can be given to
the event attribute of an action nested in a repeat. That action is then triggered once the first
time the primary instance is loaded and every time an instance of the parent repeat is added.

The odk-new-repeat event


The odk-new-repeat event is dispatched when a new instance of a repeat is added to the
primary instance and before recomputation of calculates , constraints , etc. Actions
triggered by odk-new-repeat must be nested in the repeat form control.
The odk-new-repeat event is never dispatched for repeat instances that are part of the
form definition. However, it is dispatched for repeat instances added by evaluation of
the jr:count attribute value. See creation, removal of repeats.

The following example demonstrates giving a node in a repeat a default, user-modifiable


value based on other user input:

<h:head>
<model>
...
<bind nodeset="/data/my_age" type="int" />
<bind nodeset="/data/person/age" type="int" />
<bind nodeset="/data/person/location" />
</model>
</h:head>
<h:body>
<input ref="/data/my_age">
<label>Your age</label>
</input>
...
<repeat nodeset="/data/person">
<setvalue event="odk-new-repeat" ref="/data/person/age"
value="../../my_age + 2" />
<odk:setgeopoint event="odk-new-repeat"
ref="/data/person/location" />
<input ref="/data/person/age">
<label>Person's age</label>
</input>
...
</repeat>
</h:body>

Setting a dynamic value after form load


<bind nodeset="/data/now" type="dateTime" />
<bind nodeset="/data/location" />
<setvalue event="odk-instance-first-load" ref="/data/now"
value="now()" />
<odk:setgeopoint event="odk-instance-first-load"
ref="/data/location" />

Setting a static value when a node’s value changes


<bind nodeset="/data/my_text" type="string" />
<bind nodeset="/data/my_text_changed" type="string" />
<bind nodeset="/data/my_current_location" type="string" />
...
<input ref="/data/my_text">
<setvalue event="xforms-value-changed"
ref="/data/my_text_changed">Value changed!</setvalue>
<odk:setgeopoint event="xforms-value-changed"
ref="/data/my_current_location" />
</input>

Languages
Multi-lingual content for labels, and hints is supported. This is optional and can be done by
replacing all language-dependent strings with ‘text identifiers’, which act as indexes into a
multi-lingual dictionary in the model. The language strings can be identified with
the jr:itext() XPath function.
In the <model> , a multi-lingual dictionary has the following structure:
<itext>
<translation lang="[language name]" default="true()">
<text id="[text id]">
<value>[translation of text with [text id]]</value>
</text>
</translation>
</itext>
Additional <text> entries are added for each localizable string.
The <translation> block is duplicated for each supported language. The content should
be the same (same set of text ids) but with all strings translated to the new language. The
language name in the lang attribute should be human-readable, as it is used to identify the
language in the UI. A default=”” attribute can be added to a <translation> to make it the
default language, otherwise the first listed is used as the default. Every place localized content
is used (all <label> s and <hint> s) must use a converted notation to reference the
dictionary:

For example:

<label>How old are you?</label>

is changed to:

<label ref="jr:itext('how-old')" />


With the corresponding entries in <itext> :
<translation lang="English">
...
<text id="how-old">
<value>How old are you?</value>
</text>
...
</translation>
<translation lang="Spanish">
...
<text id="how-old">
<value>¿Cuantos años tienes?</value>
</text>
...
</translation>
...
Not every string must be localized. It is acceptable to intermix <label> s of both forms.
Those which do not reference the dictionary will always show the same content, regardless of
language.
It is even allowed to intermix both a ref and a regular value. In this case, if the itext engine
is missing it will refer to the regular value. E.g.
<label ref="jr:itext('mykey')">a default value</label>

In general, all text ids must be replicated across all languages. It is sometimes only a parser
warning if you do not, but it will likely lead to headaches.

Even within a single language, it is helpful to have multiple ‘forms’ of the same string. For
example, a verbose phrasing used as the caption when answering a question, but a short, terse
phrasing when that question is shown in the form summary. This can be done using
the form attribute, as follows:
<text id="how-old-label">
<value>How old are you?</value>
<value form="short">Age</value>
</text>
<text id="how-old-hint">
<value>Enter a number</value>
<value form="guidance">If the age is less than 18, the
remainder of the survey will be hidden.</value>
</text>
There are three form attribute options for text strings:

text type attribute description

regular none Supported for <label> and <hint> content to display


regular labels and hints

short short Supported for <label> content only. It is a shorter version


version of of the label, meant for very small screens, or to be shown in
label a summary of the form data.

additional guidance Supported for <hint> content only. It is a description of


guidance the question that can be used to provide further guidance to
hint enumerators. It is not meant to be shown in the client UI by
text type attribute description

default, but could be shown in a special view mode (e.g., for


a training) or on printouts.
The media section describes how to add non-text form labels in a similar manner.

Media
The <itext> element described in the languages section can also be used for media labels.
Media labels can be used in addition to text labels or instead of text labels.
....
<itext>
<translation default=true() lang="English">
<text id="/widgets/select_widgets/grid_test/b:label">
<value form="image">jr://images/b.jpg</value>
</text>
<text id="/widgets/display_widgets/text_media:label">
<value
form="audio">jr://audio/goldeneagle.mp3</value>
<value>You can add a sound recording.</value>
</text>
</translation>
</itext>
...

Supported Media Types


 “image”
 “audio”
 “video”
 “big-image”

By default, itext “image” values are not clickable. However, if you also include a “big-
image”, the image displayed by “image” will be clickable and will display a pannable,
zoomable view of the file specified by “big-image”. The user interface must provide a way to
go back to the form after opening a “big-image”. Specifying “big-image” alone has no effect,
you must always include “image”.

Files referenced by “image” and “big-image” may be the same; however, for performance
reasons, it is recommended to create smaller thumbnail images to be referenced by “image”.

URIs
Throughout the XForm format URIs are used to refer to resources outside of the XForm itself.
The jr scheme is used to indicate the resource is available in a sandboxed environment the
client is aware of.

File Endpoints
These URIs point to files. The following are currently supported:

URI format description

jr://images/path/to/file.png Points to an image resource in the sandboxed


environment

jr://audio/path/to/file.mp3 Points to an audio resource in the sandboxed


environment

jr://video/path/to/file.mp4 Points to a video resource in the sandboxed


environment

jr://file/path/to/file.xml Points to an XML resource in the sandboxed


environment

jr://file-csv/path/to/ Points to an CSV resource in the sandboxed


file.csv environment

Virtual Endpoints
“Virtual” refers to the fact that there may or may not be an actual XML document behind the
scenes. The URI is resolved locally in any way the client desires. The following are currently
supported:

URI format description

jr://instance/last- Refers to the form instance that was saved most recently
saved (as opposed to last-opened or last-finalized, for example).

The most common use-case for this feature is to “auto-


fill” specific form fields with the last-saved value
via odk-instance-first-load .

Submission
The optional <submission> element provides instructions to the client about special
submission behavior. The element is placed as a sibling of the primary instance inside the
model.
Note that submission behavior can be highly variable between different clients. A client could
be 100% ODK-Forms-spec-compliant but have a custom way of dealing with submissions to
fit into an existing system. It is nevertheless considered helpful to document some special
behavior that clients may choose to adopt.
<model>
<instance>
<data id="mysurvey" orx:version="2014083101">
...
</data>
</instance>
<submission orx:auto-send="true" />
<bind nodeset="/data/firstname" type="xsd:string"
required="true()" />
...
</model>

Submission Attributes
The following attributes are supported on the submission element.

attribute description

action This attribute is optional and can be used to specify a custom


URL to send submissions to.

method This attribute is only required and used if


the action attribute is used. Otherwise it’s ignored. The
value should be set to post . In the past, the value form-
data-post was used. Though this is now deprecated, it is
recommended that a server accepts submissions for both
methods and considers form-data-post an alias
for post .

base64RsaPublicKey This attribute is required to enable encryption. It is a base64-


encoded RSA public key. The corresponding private key will
be needed to decrypt submissions (and should not be
included in the form definition).

orx:auto-send Optional attribute that is either "false" or "true" . If


true, any final records will be sent automatically by the client
as soon as a connection is available.
attribute description

orx:auto-delete Optional attribute that is either "false" or "true" . If


true, and successfully submitted records will be immediately
deleted from the client.

Encryption
Forms can enable encryption to provide a mechanism to keep finalized data private even
when using http: for communications (e.g., when SSL certificate is not there). It provides
security for the duration in which the data is stored on a device and on the server.
Encrypted form definitions must have an explicit <submission/> element with
a base64RsaPublicKey attribute.
The client generates a different symmetric encryption key for each finalized form and uses it
to encrypt the submission and all media files. The base64RsaPublicKey is used to
encrypt the symmetric key which is then passed back in a submission manifest.

Here is an excerpt used in an encryption-enabled XForm:

<instance>
<sample id="sample-v1.0">
<orx:meta>
<orx:instanceID/>
</orx:meta>
<name/>
</sample>
</instance>
<submission base64RsaPublicKey="MIIBIjANB...JCwIDAQAB"/>
Full details on the encryption algorithms and submission manifest can be found here.

Compact Record Representation (for SMS)


ODK XForms records are generally represented as XML using the structure of the primary
instance. It is also possible to define how a record can be represented more compactly, usually
for SMS submission.

For this representation:

 The value of the prefix attribute on the primary instance’s single child is
included at the beginning of every record.
 Questions that have a tag attribute are represented as the tag value followed by
the element’s value. Questions without a tag attribute are omitted.
 The value of the delimiter attribute on the primary instance’s single child is
used to separate components of the compact representation (prefix, tags, values).
Defaults to a single space ( ) if not explicitly specified.

Given the following ODK XForm definition:

<instance>
<household id="household_survey" orx:version="2018061801"
odk:prefix="hh" odk:delimiter="+">
<meta>
<instanceID odk:tag="id" />
</meta>
<person>
<firstname odk:tag="fn" />
<lastname odk:tag="ln" />
<age />
</person>
</household>
</instance>

Full records might look like:

<household id="household_survey" orx:version="2018061801"


odk:prefix="hh" odk:delimiter="+">
<meta>
<instanceID>uuid:82724cc5-df6f-46bf-86d5-
26683ae35d5b</instanceID>
</meta>
<person>
<firstname odk:tag="fn" />
<lastname odk:tag="ln">Bar</lastname>
<age>10</age>
</person>
</household>
<household id="household_survey" orx:version="2018061801"
odk:prefix="hh" odk:delimiter="+">
<meta>
<instanceID>uuid:82724cc5-df6f-46bf-86d5-
26683ae35d5b</instanceID>
</meta>
<person>
<firstname odk:tag="fn">Mary Kate</firstname>
<lastname odk:tag="ln">Doe</lastname>
<age>15</age>
</person>
</household>
The compact representations of those records would be: hh+ln+Bar
hh+fn+Mary Kate+ln+Doe
If the delimiter is included in one of the question values, it will be prepended by a slash. For
example, the first name "Mary Kate" would be represented as "Mary\ Kate" if the
default space delimiter is used.
As in the regular representation, nodes that are not relevant are not included in the compact
representation. Unlike in the regular representation, nodes that are relevant but empty are not
included in the compact representation, even if they have an odk:tag .

Future
See the outstanding issues list to get an idea of how this specification will evolve. Join the
conversation!

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy