XLSForm
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 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:
To collect a line or shape of GPS coordinates, you can use one of the following:
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:
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
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
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.
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
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):
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.
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:
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:
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
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:
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:
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
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
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.
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:
There are three differences when the choice list should be pulled from one of your pre-
loaded .csv files:
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.
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.
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
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.
If this column is left out or kept empty, submissions will go the default destination for the
provider you are using for your surveys.
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.
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
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
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.
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
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=".
< 10" jr:constraintMsg="number must be less than 10" />
<bind nodeset="/d/number_widgets/my_decimal" type="decimal"
constraint=". > 10.51 and . < 18.39"
jr:constraintMsg="number must be between 10.51 and 18.39" />
<bind nodeset="/d/dt/my_date" type="date" constraint=". >=
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.
expression.
Data Types
The following are acceptable data type values.
type description
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”.
barcode As string
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.
.
..
/
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.
String
Functions
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?)
after(stri g
ng,
string)
string- num Deviates from XPath 1.0 in that the argument is required.
length(str ber
ing arg)
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
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)
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.
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?)
Node-set
Functions
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.
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
decimal- num Converts dateTime value to the number of days since January 1,
date- ber 1970 UTC.
time(dateT
ime value)
Select
Functions
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)
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
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.
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.
Audit Attributes
attribute description
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.
<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.
<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.
<repeat> Child of <body> or <group> that can be repeated. See repeats for
further details.
element description
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)
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
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.
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.
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>
...
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
See the W3C XForms specification section on events. The following events are supported:
event description
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.
<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>
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:
is changed to:
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:
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>
...
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:
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:
jr://instance/last- Refers to the form instance that was saved most recently
saved (as opposed to last-opened or last-finalized, for example).
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
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.
<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.
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.
<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>
Future
See the outstanding issues list to get an idea of how this specification will evolve. Join the
conversation!