Structured Data Capture, published by HL7 International / FHIR Infrastructure. This guide is not an authorized publication; it is the continuous build for version 4.0.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/HL7/sdc/ and changes regularly. See the Directory of published versions
| Official URL: http://hl7.org/fhir/uv/sdc/StructureMap/QuestionnairePopulationTransform | Version: 4.0.0 | |||
| Standards status: Trial-use Draft as of 2025-10-22 | Maturity Level: 4 | Computable Name: QuestionnairePopulationTransform | ||
| Other Identifiers: OID:2.16.840.1.113883.4.642.40.17.43.4 | ||||
/// name = "QuestionnairePopulationTransform"
/// status = "active"
/// title = "Questionnaire Population Transform Example"
/// description = "An example of a StructureMap used to support population of a QuestionnaireResponse from a search bundle"
/// experimental = "true"
map "http://hl7.org/fhir/uv/sdc/StructureMap/QuestionnairePopulationTransform" = "QuestionnairePopulationTransform"
uses 'http://hl7.org/fhir/StructureDefinition/Bundle' as source
uses 'http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse' as target
uses 'http://hl7.org/fhir/StructureDefinition/MedicationStatement' as source
// The input bundle is a search bundle that contains search bundles for patient, condition, and medication statement resources
group main(source src : Bundle, target qr : QuestionnaireResponse) {
src -> qr.questionnaire = 'http://hl7.org/fhir/uv/sdc/Questionnaire/questionnaire-sdc-test-fhirpath-prepop-source-query' "questionnaire";
src -> qr.status = 'in-progress' "status";
src -> qr.authored = (now()) "authored";
src.entry first as patient -> qr.subject as subject, subject.reference = (%patient.resource.entry.fullUrl.toString()) "subject";
src -> qr.item as grp, grp.linkId = 'grp' then {
src -> grp.item as partDetails, partDetails.linkId = 'part-details' then {
src.entry first as patient then {
patient.resource : Bundle as patientRes -> partDetails then populatePatientGroup(patientRes, partDetails) "partBundleDetails";
} "patientDetails";
src.entry as conditions where (resource.link.url.contains("/Condition?")) -> partDetails.item as conditionItem, conditionItem.linkId = 'condition-count' then {
conditions -> conditionItem.answer as conditionCountAnswer, conditionCountAnswer.value = (%conditions.resource.entry.count()) "conditionCountAnswer";
} "conditionCount";
} "partDetails";
// Scan the search bundle for a medication statement bunde
src.entry as medications where (resource.link.url.contains("/MedicationStatement?")) -> grp then {
medications.resource : Bundle as medRes then populateMedicationsGroup(medRes, grp) "medEntry";
} "meds";
} "grp";
}
group populatePatientGroup(source patientRes : Bundle, target partDetails) {
patientRes -> partDetails.item as participantId,
participantId.linkId = 'participant-id',
participantId.answer as participantIdAnswer,
participantIdAnswer.value = (%patientRes.entry.resource.id.toString()) "participantIdValue";
patientRes -> partDetails.item as familyName,
familyName.linkId = 'family-name',
familyName.answer as familyNameAnswer,
familyNameAnswer.value = (%patientRes.entry.resource.name.first().family) "familyNameValue";
patientRes -> partDetails.item as givenName,
givenName.linkId = 'given-names',
givenName.answer as givenNameAnswer,
givenNameAnswer.value = (%patientRes.entry.resource.name.first().given.join(', ')) "givenNameValue";
patientRes -> partDetails.item as dob,
dob.linkId = 'dob',
dob.answer as dobAnswer,
dobAnswer.value = (%patientRes.entry.resource.birthDate) "dobValue";
}
group populateMedicationsGroup(source medRes : Bundle, target grp) {
medRes.entry as med where (resource is MedicationStatement) -> grp.item as medsItem, medsItem.linkId = 'meds' then {
med.resource : MedicationStatement as medResource -> medsItem.item as medsName,
medsName.linkId = 'med-name',
medsName.answer as medsNameAnswer,
medsNameAnswer.value = (%medResource.medication.select(iif(text.exists(), text, coding.display.first()))) "medsNameAnswer";
/* Todo handle medicationReference once resolve is supported
iif($this is Reference, iif($this.resolve().text.exists(), $this.resolve().text, $this.resolve().coding.display.first()), iif(text, text, coding.display.first())))) "medsNameAnswer";
*/
med.resource : MedicationStatement as medResource -> medsItem.item as medsStatus, medsStatus.linkId = 'med-status' then {
medResource.status as medsMedicationStatus -> medsStatus.answer as medsStatusAnswer, medsStatusAnswer.value = c('http://hl7.org/fhir/CodeSystem/medication-status', medsMedicationStatus) "medsStatusAnswer";
} "medsStatus";
med.resource as medResource where (category.coding.where(system='http://terminology.hl7.org/CodeSystem/medicationrequest-category').exists()) -> medsItem.item as medsCategory, medsCategory.linkId = 'meds-category' then {
medResource -> medsCategory.answer as medsCategoryAnswer, medsCategoryAnswer.value = (%medResource.category.coding.where(system='http://terminology.hl7.org/CodeSystem/medicationrequest-category').code.join(' ')) "medsCategoryAnswer";
} "medsCategory";
} "medItem";
}