ART-DECOR® Questionnaires
0.5.0 - ci-build
ART-DECOR® Questionnaires - Local Development build (v0.5.0) built by the FHIR (HL7® FHIR® Standard) Build Tools. See the Directory of published versions
FHIR SDC supports automatic score and value calculation directly within a Questionnaire resource using FHIRPath expressions. This page describes the approach used in this implementation guide, illustrated by the Apgar score questionnaires.
Reference: SDC – Calculations
A calculated item (e.g., a total score) requires the following building blocks on the score item (type = #decimal):
| Role | Extension | Purpose |
|---|---|---|
| Intermediate variable | variable |
Extracts the weight of a selected answer option into a named FHIRPath variable |
| Computed value | calculatedExpression (SDC) |
Sums the variables and populates the item answer |
| Unit label | questionnaire-unit |
Attaches a UCUM unit (e.g. score) to the item |
And on each answer option of a choice item contributing to the score:
| Role | Extension | Purpose |
|---|---|---|
| Item weight | itemWeight |
Numeric value assigned to the option, used in score computation |
Each answer option of a #choice item receives an itemWeight extension with its numeric score value:
{
"answerOption": [
{
"valueCoding": {
"system": "http://loinc.org",
"code": "LA6716-0",
"display": "No heart rate"
},
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/itemWeight",
"valueDecimal": 0
}
]
},
{
"valueCoding": {
"system": "http://loinc.org",
"code": "LA6717-8",
"display": "Under 100 beats per minute"
},
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/itemWeight",
"valueDecimal": 1
}
]
}
]
}
On the score item, one variable extension is added per contributing choice item. Use the helper function .answer.weight() to read the itemWeight value of the selected answer:
{
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/variable",
"valueExpression": {
"name": "a",
"language": "text/fhirpath",
"expression": "%resource.item.where(linkId = '32406-1').answer.weight()"
}
}
]
}
Pattern: For each contributing item with linkId = 'X', define a variable that resolves to the weight of the currently selected answer (using %resource.item.where(linkId='X').answer.weight()), or {} (empty) if no answer has been selected yet.
Tip: Use short single-letter variable names (
%a,%b, …) when there are many items to keep expressions readable.
The calculatedExpression extension computes the final score. Simply sum the variables:
{
"extension": [
{
"url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression",
"valueExpression": {
"description": "Total score (only when all 5 answered)",
"language": "text/fhirpath",
"expression": "%a + %b + %c + %d + %e"
}
}
]
}
If any variable is empty ({}), the entire sum returns {} (empty). This means the score field automatically stays empty until all contributing items have been answered — no explicit iif needed.
Arithmetic operators in FHIRPath (+, -, *, /) expect each operand to evaluate to at most one value (0..1) (or {}).
If an expression returns multiple values (e.g., because an item allows repeats or uses a checkbox-style answer), the calculation may fail or behave unexpectedly because FHIRPath does not implicitly aggregate.
Recommendation: Ensure each variable resolves to a singleton. For multi-answer items, aggregate explicitly, e.g. ...answer.weight().sum(), or select a single value intentionally, e.g. ...first().
readOnlyBecause the score is calculated automatically, the item must be marked readOnly = true. This prevents the user from manually overwriting the computed value and signals to the renderer that no input control should be shown:
{
"linkId": "9272-6",
"text": "1-Min Apgar Total Score",
"type": "decimal",
"readOnly": true,
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/variable",
"valueExpression": { "..." : "..." }
}
]
}
{
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/questionnaire-unit",
"valueCoding": {
"system": "http://unitsofmeasure.org",
"code": "1",
"display": "score"
}
}
]
}
Use a UCUM code to describe the unit of the calculated value. For dimensionless scores the code 1 is used with a human-readable display "score".
See the Apgar score questionnaires for a full working implementation:
Instead of placing itemWeight extensions directly on each answerOption, weights can be declared centrally in a ValueSet expansion. This separates the scoring logic from the Questionnaire and enables reuse across multiple items or questionnaires.
This approach uses two FHIR 5.0 backport extensions:
| Extension | URL | Purpose |
|---|---|---|
extension-ValueSet.expansion.property |
http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.property |
Declares itemWeight as a named property on the expansion |
extension-ValueSet.expansion.contains.property |
http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property |
Assigns the weight value to each concept in the expansion |
1. Declare the property on the expansion:
{
"expansion": {
"extension": [
{
"url": "http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.property",
"extension": [
{
"url": "code",
"valueCode": "itemWeight"
},
{
"url": "uri",
"valueUri": "http://hl7.org/fhir/concept-properties#itemWeight"
}
]
}
]
}
}
2. Assign a weight to each concept:
{
"expansion": {
"contains": [
{
"system": "http://loinc.org",
"code": "LA6716-0",
"display": "No heart rate",
"extension": [
{
"url": "http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property",
"extension": [
{
"url": "code",
"valueCode": "itemWeight"
},
{
"url": "value",
"valueDecimal": 0
}
]
}
]
}
]
}
}
.answer.weight() with a bound ValueSetWhen a #choice item is bound to a ValueSet that carries weights in its expansion, the .answer.weight() FHIRPath function resolves the weight from the expansion automatically — no itemWeight on the answerOption is needed:
Choice item bound to the ValueSet:
{
"linkId": "32406-1",
"type": "choice",
"answerValueSet": "http://loinc.org/vs/LL385-6"
}
On the score item:
{
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/variable",
"valueExpression": {
"name": "a",
"language": "text/fhirpath",
"expression": "%resource.item.where(linkId = '32406-1').answer.weight()"
}
}
]
}
See Apgar Pulse ValueSet (LL385-6) for a working example with weights embedded in the expansion.
| Extension | URL | Scope |
|---|---|---|
variable |
http://hl7.org/fhir/StructureDefinition/variable |
item |
calculatedExpression |
http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression |
item |
questionnaire-unit |
http://hl7.org/fhir/StructureDefinition/questionnaire-unit |
item |
itemWeight |
http://hl7.org/fhir/StructureDefinition/itemWeight |
answerOption |
extension-ValueSet.expansion.property |
http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.property |
ValueSet.expansion |
extension-ValueSet.expansion.contains.property |
http://hl7.org/fhir/5.0/StructureDefinition/extension-ValueSet.expansion.contains.property |
ValueSet.expansion.contains |