Skip to main content
Resource Publishing

Patient Questionnaire Template Schema

A patient questionnaire template defines a form presented to patients (for example via the patient portal). Each field can optionally file a coded entry to the patient's care record when the form is submitted.

The current schema version is 2.0. The version attribute on the root element is fixed and must be set to 2.0.

Example

<?xml version="1.0" encoding="UTF-8"?>
<patientQuestionnaire xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
<documentCode code="719091000000102"/>
<additionalFilingCodes>
<careRecordNote code="160303001"/>
</additionalFilingCodes>
<form>
<title>Pre-appointment Health Check</title>
<description>Please complete this form before your appointment.</description>
<infoBanner title="About this form" text="Your answers help the clinician prepare for your visit."/>
<checkboxGroup name="symptoms" label="Current symptoms" required="false">
<checkboxOption label="Shortness of breath" value="sob">
<ifChecked>
<careRecordNote code="230145002"/>
</ifChecked>
</checkboxOption>
<checkboxOption label="Chest pain" value="chest-pain">
<ifChecked>
<careRecordNote code="29857009"/>
</ifChecked>
</checkboxOption>
</checkboxGroup>
<radioGroup name="smoking" label="Smoking status" required="true">
<radioOption label="Non-smoker" value="non-smoker">
<ifSelected>
<careRecordNote code="266919005"/>
</ifSelected>
</radioOption>
<radioOption label="Current smoker" value="smoker">
<ifSelected>
<careRecordNote code="77176002"/>
</ifSelected>
</radioOption>
</radioGroup>
<quantity name="weight" label="Weight (kg)" required="false">
<ifValueSet>
<careRecordObservation code="27113001" unitOfMeasure="258683005"/>
</ifValueSet>
</quantity>
<dateInput name="last_bp_date" label="Date of last blood pressure reading">
<ifValueSet>
<careRecordObservation code="75367002"/>
</ifValueSet>
</dateInput>
<textarea name="notes" label="Any other information" required="false">
<ifTextSet>
<careRecordNote code="37193005"/>
</ifTextSet>
</textarea>
</form>
</patientQuestionnaire>

Schema

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:simpleType name="snomedCode">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9]+"/>
<xs:minLength value="6"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="nonEmptyString">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
</xs:restriction>
</xs:simpleType>
<xs:attributeGroup name="topLevelFormElementAttributes">
<xs:attribute name="name" use="required">
<xs:simpleType>
<xs:restriction base="xs:ID">
<xs:pattern value="[A-Za-z][A-Za-z0-9_]+"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="label" type="xs:string"/>
<xs:attribute name="required" type="xs:boolean"/>
</xs:attributeGroup>
<xs:complexType name="layoutElementContainerType">
<xs:sequence>
<xs:element name="title" type="nonEmptyString"/>
<xs:element name="description" minOccurs="0" type="xs:string"/>
<!-- Permit any of these tags in any order in any number -->
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="infoBanner"/>
<xs:element ref="checkbox"/>
<xs:element ref="checkboxGroup"/>
<xs:element ref="radioGroup"/>
<xs:element ref="select"/>
<xs:element ref="textInput"/>
<xs:element ref="textarea"/>
<xs:element ref="quantity"/>
<xs:element ref="dateInput"/>
<xs:element ref="time"/>
<xs:element ref="bloodPressure"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:complexType name="topLevelFormElementType">
<xs:attributeGroup ref="topLevelFormElementAttributes"/>
</xs:complexType>
<xs:element name="patientQuestionnaire">
<xs:complexType>
<xs:sequence>
<xs:element ref="documentCode"/>
<xs:element ref="additionalFilingCodes" minOccurs="0"/>
<xs:element ref="form"/>
</xs:sequence>
<xs:attribute name="version" use="required" fixed="2.0"/>
</xs:complexType>
</xs:element>
<xs:element name="form">
<xs:complexType>
<xs:complexContent>
<xs:extension base="layoutElementContainerType">
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="documentCode">
<xs:complexType>
<xs:attribute name="code" type="snomedCode" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="additionalFilingCodes">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="careRecordNote" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="careRecordAllergyIntolerance" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="careRecordObservation" minOccurs="0" maxOccurs="unbounded"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="title" type="xs:string"/>
<!-- LAYOUT ELEMENTS -->
<xs:element name="infoBanner">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="title" type="xs:string"/>
<xs:attribute name="text" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<!-- FORM ELEMENTS -->
<xs:element name="checkbox">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="ifChecked"/>
</xs:all>
<xs:attributeGroup ref="topLevelFormElementAttributes"/>
<xs:attribute name="text" use="required" type="nonEmptyString"/>
<xs:attribute name="value" use="required" type="nonEmptyString"/>
</xs:complexType>
</xs:element>
<xs:element name="checkboxGroup">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="checkboxOption"/>
</xs:sequence>
<xs:attributeGroup ref="topLevelFormElementAttributes"/>
<xs:attribute name="twoColumns" type="xs:boolean"/>
</xs:complexType>
<xs:key name="checkboxOptionValue">
<xs:selector xpath="./checkboxOption"/>
<xs:field xpath="@value"/>
</xs:key>
</xs:element>
<xs:element name="checkboxOption">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="ifChecked"/>
</xs:all>
<xs:attribute name="label" use="required" type="nonEmptyString"/>
<xs:attribute name="value" use="required" type="nonEmptyString"/>
</xs:complexType>
</xs:element>
<xs:element name="radioGroup">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="radioOption"/>
</xs:sequence>
<xs:attributeGroup ref="topLevelFormElementAttributes"/>
</xs:complexType>
<xs:key name="radioOptionValue">
<xs:selector xpath="./radioOption"/>
<xs:field xpath="@value"/>
</xs:key>
</xs:element>
<xs:element name="radioOption">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="ifSelected"/>
</xs:all>
<xs:attribute name="label" use="required" type="nonEmptyString"/>
<xs:attribute name="value" use="required" type="nonEmptyString"/>
</xs:complexType>
</xs:element>
<xs:element name="select">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="selectOption"/>
</xs:sequence>
<xs:attributeGroup ref="topLevelFormElementAttributes"/>
</xs:complexType>
<xs:key name="selectOptionValue">
<xs:selector xpath="./selectOption"/>
<xs:field xpath="@value"/>
</xs:key>
</xs:element>
<xs:element name="selectOption">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="ifSelected"/>
</xs:all>
<xs:attribute name="label" use="required" type="nonEmptyString"/>
<xs:attribute name="value" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="textInput">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="ifTextSet"/>
</xs:all>
<xs:attributeGroup ref="topLevelFormElementAttributes"/>
</xs:complexType>
</xs:element>
<xs:element name="textarea">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="ifTextSet"/>
</xs:all>
<xs:attributeGroup ref="topLevelFormElementAttributes"/>
</xs:complexType>
</xs:element>
<xs:element name="quantity">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="ifValueSet"/>
</xs:all>
<xs:attributeGroup ref="topLevelFormElementAttributes"/>
<xs:attribute name="maxValue" type="xs:float"/>
<xs:attribute name="minValue" type="xs:float"/>
</xs:complexType>
</xs:element>
<xs:element name="dateInput">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" ref="ifValueSet"/>
</xs:all>
<xs:attributeGroup ref="topLevelFormElementAttributes"/>
<xs:attribute name="maxDate" type="xs:date"/>
<xs:attribute name="minDate" type="xs:date"/>
</xs:complexType>
</xs:element>
<xs:element name="time" type="topLevelFormElementType"/>
<xs:element name="bloodPressure">
<xs:complexType>
<xs:all>
<xs:element ref="ifValueSet"/>
</xs:all>
<xs:attributeGroup ref="topLevelFormElementAttributes"/>
<xs:attribute name="decimalPlaces" type="xs:string"/>
<xs:attribute name="maxValue" type="xs:float"/>
<xs:attribute name="minValue" type="xs:float"/>
</xs:complexType>
</xs:element>
<xs:element name="footer" type="xs:string"/>
<xs:element name="code" type="snomedCode"/>
<xs:element name="ifChecked">
<xs:complexType>
<xs:choice>
<xs:element ref="careRecordNote"/>
<xs:element ref="careRecordAllergyIntolerance"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="ifSelected">
<xs:complexType>
<xs:choice>
<xs:element ref="careRecordNote"/>
<xs:element ref="careRecordAllergyIntolerance"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="ifTextSet">
<xs:complexType>
<xs:all>
<xs:element ref="careRecordNote"/>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="ifValueSet">
<xs:complexType>
<xs:choice>
<xs:element ref="careRecordObservation"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="careRecordNote">
<xs:complexType>
<xs:attribute name="code" use="required" type="snomedCode"/>
<xs:attribute name="note" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="careRecordAllergyIntolerance">
<xs:complexType>
<xs:attribute name="code" use="required" type="snomedCode"/>
</xs:complexType>
</xs:element>
<xs:element name="careRecordObservation">
<xs:complexType>
<xs:attribute name="code" use="required" type="snomedCode"/>
<xs:attribute name="unitOfMeasure" type="snomedCode"/>
</xs:complexType>
</xs:element>
</xs:schema>

Form controls

ElementDescriptionCare record hook
infoBannerInformational banner with optional title and text attributes.None
checkboxSingle checkbox. Requires text and value attributes.ifChecked
checkboxGroupMultiple checkboxes. Each checkboxOption has label and value.ifChecked per option
radioGroupRadio buttons. Each radioOption has label and value.ifSelected per option
selectDropdown. Each selectOption has label and value.ifSelected per option
textInputSingle-line text field.ifTextSet
textareaMulti-line text field.ifTextSet
quantityNumeric field. Optional minValue and maxValue.ifValueSet
dateInputDate picker. Optional minDate and maxDate (YYYY-MM-DD).ifValueSet
timeTime picker.None
bloodPressureBlood pressure entry. Optional minValue, maxValue, decimalPlaces.ifValueSet (required)

Care record filing

Each applicable control can file to the patient's care record when the patient responds:

HookUsed withFiles as
ifCheckedcheckbox, checkboxOptioncareRecordNote or careRecordAllergyIntolerance
ifSelectedradioOption, selectOptioncareRecordNote or careRecordAllergyIntolerance
ifTextSettextInput, textareacareRecordNote
ifValueSetquantity, dateInput, bloodPressurecareRecordObservation

careRecordNote requires a SNOMED CT concept ID and accepts an optional note string. careRecordAllergyIntolerance requires a SNOMED CT concept ID. careRecordObservation requires a SNOMED CT concept ID and optionally a unitOfMeasure SNOMED CT concept ID.