FHIR Schema

FHIR Schema makes FHIR easier to work with, improving interoperability of healthcare systems.

FHIR Schema is a project designed to simplify the implementation and validation of FHIR (Fast Healthcare Interoperability Resources) resources across different programming languages. It is heavily inspired by the design of JSON Schema and introduces a more developer-friendly representation of FHIR StructureDefinitions.

FHIR Schema Status: Trial Use

Key features

  • Simple and Intuitive Structure
  • Explicit Arrays
  • Clear Operational Semantics
  • Human- and machine-readable format at the same time
  • Logical models are as easy as regular

Motivation

  • there are only few implementations of FHIR validation - why? because it's hard, no unit-tests, esoteric knowledge
  • we need more in different languages python, js, golang, rust etc
  • every implementers doing similar transformtions to SD (it looks very like JSON schema than StructureDef)
    • most of implementers do convert SD to nested data structure
    • care about arrays (max: *)
    • resolve references
  • snapshots is implementation detail leaking into standard, only-differential validation sounds better
  • People need simple source of metadata for code-generation and FHIRPath

US Core Patient Profile

In this tutorial, we will create a US Core Patient Profile on FHIRSchema from scratch.

1. Base type

Since the profile describe the patient structure, it is important to inherit from its base profile.

base: Patient

Read more - Base type

2. Profile Identifier

Specify the profile's global canonical identifier.

base: Patient
url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient

Read more - Profile url

3. Required elements

Specify the fields that must be present in the data.

  • Patient.name
  • Patient.gender
  • Patient.identifier
  • Patient.identifier.system
  • Patient.identifier.value
  • Patient.telecom.system
  • Patient.telecom.value
base: Patient
url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient
required: [identifier, name, gender]
elements:
  identifier:
    required: [system, value]
  telecom:
    required: [system, value]

Read more - Requires and exclusions

4. Slicing

Describe slicing on extensions using a short notation. Specify that in Patient.extension, there can be four extensions, and no more than one of each.

base: Patient
url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient
extensions:
  us-core-race:
    url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-race
    max: 1
  us-core-ethnicity:
    url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity
    max: 1
  us-core-birthsex:
    url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-birthsex
    max: 1
  us-core-genderIdentity:
    url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-genderIdentity
    max: 1
required: [identifier, name, gender]
elements:
  identifier:
    required: [system, value]
  telecom:
    required: [system, value]

Read more - Slicing

5. Constraints

Describe a constraint using FHIRPath syntax that define the rule:

A patient's name must contain either a family name or a given name; otherwise, there must be an extension explaining the absence of the name.

base: Patient
url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient
extensions:
  us-core-race:
    url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-race
    max: 1
  us-core-ethnicity:
    url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity
    max: 1
  us-core-birthsex:
    url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-birthsex
    max: 1
  us-core-genderIdentity:
    url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-genderIdentity
    max: 1
constraints:
  us-core-6:
    severity: error 
    expression: "(name.family.exists() or name.given.exists()) xor extension.where(url='http://hl7.org/fhir/StructureDefinition~/data-absent-reason').exists()"
    human: "Either Patient.name.given and/or Patient.name.family SHALL be present or a Data Absent Reason Extension SHALL be pr~esent."
required: [identifier, name, gender]
elements:
  identifier:
    required: [system, value]
  telecom:
    required: [system, value]

Read more - Constraints

6. Terminology bindings

Specify the terminological bindings for coded values.

  • Patient.telecom.system - ContactPointSystem (required)
  • Patient.telecom.use - ContactPointUse (required)
  • Patient.address.state - USPS Two Letter Alphabetic Codes (extensible)
  • Patient.communication.language - Language codes (extensible)
base: Patient
url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient
extensions:
  us-core-race:
    url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-race
    max: 1
  us-core-ethnicity:
    url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity
    max: 1
  us-core-birthsex:
    url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-birthsex
    max: 1
  us-core-genderIdentity:
    url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-genderIdentity
    max: 1
constraints:
  us-core-6:
    severity: error 
    expression: "(name.family.exists() or name.given.exists()) xor extension.where(url='http://hl7.org/fhir/StructureDefinition~/data-absent-reason').exists()"
    human: "Either Patient.name.given and/or Patient.name.family SHALL be present or a Data Absent Reason Extension SHALL be pr~esent."
required: [identifier, name, gender]
elements:
  identifier:
    required: [system, value]
  telecom:
    required: [system, value]
    elements:
      system: 
        binding:
          strength: required
          valueSet: http://hl7.org/fhir/ValueSet/contact-point-system
      use:
        binding:
          strength: required
          valueSet: http://hl7.org/fhir/ValueSet/contact-point-use
  gender:
    binding:
      strength: required
      valueSet: http://hl7.org/fhir/ValueSet/administrative-gender
  address:
    elements:
      state:
        binding:
          strength: extensible
          valueSet: http://hl7.org/fhir/us/core/ValueSet/us-core-usps-state
  communication:
    elements:
      language:
        binding:
          strength: extensible
          valueSet: http://hl7.org/fhir/us/core/ValueSet/simple-language

Read more - Terminology bindings

7. Flags

Indicate the mustSupport flag to describe that systems claiming to conform to a given profile must "support" the element.

base: Patient
url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient
extensions:
  us-core-race:
    url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-race
    max: 1
  us-core-ethnicity:
    url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity
    max: 1
  us-core-birthsex:
    url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-birthsex
    max: 1
  us-core-genderIdentity:
    url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-genderIdentity
    max: 1
constraints:
  us-core-6:
    severity: error 
    expression: "(name.family.exists() or name.given.exists()) xor extension.where(url='http://hl7.org/fhir/StructureDefinition~/data-absent-reason').exists()"
    human: "Either Patient.name.given and/or Patient.name.family SHALL be present or a Data Absent Reason Extension SHALL be pr~esent."
required: [identifier, name, gender]
elements:
  identifier:
    required: [system, value]
    mustSupport: true
    elements:
      system: 
        mustSupport: true
      value: 
        mustSupport: true
  name:
    elements:
      family:
        mustSupport: true
      given:
        mustSupport: true
  telecom:
    required: [system, value]
    elements:
      system: 
        mustSupport: true
        binding:
          strength: required
          valueSet: http://hl7.org/fhir/ValueSet/contact-point-system
      value: 
        mustSupport: true
      use: 
        mustSupport: true
        binding:
          strength: required
          valueSet: http://hl7.org/fhir/ValueSet/contact-point-use
  gender:
    mustSupport: true
    binding:
      strength: required
      valueSet: http://hl7.org/fhir/ValueSet/administrative-gender
  birthDate:
    mustSupport: true
  address:
    mustSupport: true
    elements:
      line:
        mustSupport: true
      city:
        mustSupport: true
      state:
        mustSupport: true
         binding:
           strength: extensible
           valueSet: http://hl7.org/fhir/us/core/ValueSet/us-core-usps-state
      postalCode:
        mustSupport: true
      period:
        mustSupport: true
  communication:
    elements:
      language:
        mustSupport: true
        binding:
          strength: extensible
          valueSet: http://hl7.org/fhir/us/core/ValueSet/simple-language

Read more - Element flags

Validation

We will distinguish data elements, and schema elements. Data element is a part of the data, schema element is a part of schema.

FHIR Schema uses differential schemas for data description. To validate a data element we need to collect all element schemas covering this data element.

There are multiple properties which are used to refer other schema covering a data element.

Root schemas have a property referring to another schema: base. Element schemas have 2 properties referring to another schemas: type and elementReference.

We will call a set of all schemas covering a data element a schemata.

Schemata resolution

To resolve schemata we always start a root schema. Consider two operations: collect and follow.

The collect operation accepts a set S of schemas, and for each schema s adds referred schemas to the set S.

More formally, let getBaseSchema be a function which accepts a root schema and returns

  • a singleton set with the schema referred by the base property, if both the property is present and the referred schema exists,
  • empty set, otherwise

Let getTypeSchema be a function which accepts an element schema and returns

  • a singleton set with the schema referred by the type property, if both the property is present and the referred schema exists,
  • empty set, otherwise

Let getElementReferenceSchema be a function which accepts an element schema and returns

  • a singleton set with the schema referred by the elementReference property, if both the property is present and the referred schema exists,
  • empty set, otherwise

Define \[ \operatorname{collect}(S) = \bigcup_{s \in S} \begin{cases} \{s\} \cup \operatorname{getBaseSchema}(s), \text{if s is a root schema},\\ \{s\} \cup \operatorname{getTypeSchema}(s) \cup \operatorname{getElementReferenceSchema}(s), \text{otherwise}. \end{cases} \]

The follow operation accepts a set S of schemas and a path item p, and for each schema s it constructs a set S' of schemas following the element p.

I.e. \[ \operatorname{follow}(S) = \bigcup_{s \in S} \{ s\texttt{.elements.}p \mid s\texttt{.elements.}p \text{ exists} \} \]

To resolve schemata for data element at path P,

  1. Start with a singleton set with the root schema,
  2. Repeat the collect operation until the set stops growing
  3. Take first path item p from path P
  4. Apply the follow opertion using the schemata set
  5. Repeat the collect operation until the set stops growing
  6. Repeat starting from 3. with remaining path

Example

Consider US Core patient and name.given element The schemata set changes:

  1. start with US Core Patient schema
  2. collect: US Core Patient schema, FHIR R4 patient schema
  3. collect: US Core Patient, R4 Patient, R4 DomainResource
  4. collect: US Core Patient, R4 Patient, R4 DomainResource, R4 Resource
  5. collect: US Core Patient, R4 Patient, R4 DomainResource, R4 Resource (stops growing)
  6. follow: US Core Patient name element, R4 Patient name element
  7. collect: US Core Patient name element, R4 Patient name element, R4 HumanName
  8. collect: US Core Patient name element, R4 Patient name element, R4 HumanName, R4 Element
  9. collect: US Core Patient name element, R4 Patient name element, R4 HumanName, R4 Element (stops growing)
  10. follow: US Core Patient name.given element, R4 HumanName.given element
  11. collect: US Core Patient name.given element, R4 HumanName.given element, R4 string
  12. collect: US Core Patient name.given element, R4 HumanName.given element, R4 string, R4 element
  13. collect: US Core Patient name.given element, R4 HumanName.given element, R4 string, R4 element (stops growing)

Data element validation

Data element is checked against each schema from schemata. Rules differ by JSON node type:

  • Object:
    • Validate the object against each schema from schemata;
    • Validate every property of the object;
    • Check that each object property has non-empty schemata.
  • Array: Validate every entry of the object.
  • Other: Validate the node.

If the node is accepted by each schema, it is accepted, otherwise rejected.

Primitive element validation

FHIR has a much wider types vocabulary than JSON. So, in addition to regular validation rules, apply primitive datatype validation according to FHIR specification.

E.g. check format of a dateTime value, which is represented as a string 2024-02-30.

Schema

The schema defines elements and specifies constraint rules, which are applied on top of base schemas.

Syntax

Properties applicable only to schema

All properties are required

URL property

  • url : string

Resource type property

  • type : string

Name property

  • name : string

Derivation property

  • derivation : specialization or constraint

Optional properties

Base type property

  • base : string

Properties shared with elements

Requires and exclusions properties

  • excluded (array of strings)
  • required (array of strings)

Nested elements property

  • elements (object)

Constraints property

  • constraints

Extensions property

  • extensions

Base

The base property defines the base profile from which schema will inherit all elements and constraints

Example

You can create resource with base profile of US Core Patient:

url: http://example.com/patient
base: http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient|6.0.0
type: Patient
name: ExamplePatient

Valid Patient resource:

resourceType: Patient
meta:
  profile:
  - http://example.com/patient
identifier:
- system: exampleSystem
  value: exampleValue
gender: male
name:
- given:
  - Example name

Invalid Patient resource with wrong gender type:

resourceType: Patient
meta:
  profile:
  - http://example.com/patient
identifier:
- system: exampleSystem
  value: exampleValue
gender: true # wrong type
name:
- given:
  - Example name

Derivation

The derivation property defines the type of described object of FHIR Schema: specialization for custom resources and constraint for profiles (see details: TypeDerivationRule)

Examples

  • The custom resource with specialization:
url: http://example.com/Foo
base: http://hl7.org/fhir/StructureDefinition/Resource
name: Foo
type: Foo
derivation: specialization
  • The profile with constraint:
url: http://example.com/Foo-Bar-profile
base: Foo
name: Bar
type: Foo
derivation: constraint

URL

The url is used to reference the profile in base property in other profiles.

Example

After creating profile with following url:

base: http://hl7.org/fhir/StructureDefinition/Patient
url: http://example.com/Patient/patient
elements:
  new-element:
    type: string

You can reference it, for example, in base property from another profile:

base: http://example.com/Patient/patient|1.0.0

Or you can reference it with meta.profile in resource, if you want to validate resource against not default profile:

Valid Patient resource

meta:
  profile: http://example.com/Patient/patient|1.0.0
new-element: "Example"

Invalid Patient resource with wrong elements type

meta:
  profile: http://example.com/Patient/patient|1.0.0
new-element: true

Resource type

The type property defines which resource type being constrained. The type must match with type property of base profile.

Example:

base: http://hl7.org/fhir/StructureDefinition/Patient
type: Patient

Name

Property name is machine readable name of profile. It is can be used as alias.

Example

After creating profile

name: ExamplePatient

You can reference it with name in other profiles


elements:
  a:
    refers: [ExamplePatient]

Element

Element is a FHIR Schema component which defines or constrains FHIR data type.

Syntax

All properties are optional.

Shape properties

  • array (boolean)
  • scalar (boolean)

Cardinality properties

  • min (integer)
  • max (integer)

Choice type properties

  • choiceOf (string)
  • choices (array of strings)

Requires and exclusions properties

  • excluded (array of strings)
  • required (array of strings)

Type reference properties

  • elementReference (array of strings)
  • type (string)

Nested elements property

  • elements (object)

Constraints property

  • constraints (Constraint)

Slicing property

  • slicing (Slicing)

Terminology binding property

  • binding (Binding): valueset binding\

Pattern matching (constants definition) property

  • fixed (any)
  • pattern (any)

Reference target property

  • refers (array of strings)

Informational properties

  • modifier (boolean)
  • mustSupport (boolean)
  • summary (boolean)

Shape

There are 2 properties controlling element shape:

  • array
  • scalar

The array and scalar properties control element structure. These 2 properties are mutually exclusive. I.e. the folowing element is invalid.

array: true
scalar: true
  • If array is set, only JSON arrays are accepted.
  • If scalar is set, JSON arrays are rejected.
  • If neither is set, everything is accepted.

Empty arrays are rejected (they are not allowed by FHIR).

Example

Consider this part of FHIR R4 Core Patient schema:

id: Patient
url: http://hl7.org/fhir/StructureDefinition/Patient
package-meta:
  name: hl7.fhir.r4.core
  version: 4.0.1
  path: "/tmp/lw-fhir-schema-repository/hl7.fhir.r4.core#4.0.1"
base: http://hl7.org/fhir/StructureDefinition/DomainResource
kind: resource
type: Patient
derivation: specialization
elements:
  deceasedBoolean:
    scalar: true
    summary: true
    modifier: true
    type: boolean
    choiceOf: deceased
  maritalStatus:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/marital-status
      strength: extensible
    scalar: true
    type: CodeableConcept
  deceasedDateTime:
    scalar: true
    summary: true
    modifier: true
    type: dateTime
    choiceOf: deceased
  managingOrganization:
    refers:
    - http://hl7.org/fhir/StructureDefinition/Organization
    scalar: true
    summary: true
    type: Reference
  gender:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/administrative-gender
      strength: required
      codesystems:
      - http://hl7.org/fhir/administrative-gender
    type: code
    scalar: true
    summary: true
  multipleBirth:
    choices:
    - multipleBirthBoolean
    - multipleBirthInteger
    scalar: true
  name:
    summary: true
    type: HumanName
    array: true
  address:
    summary: true
    type: Address
    array: true
  identifier:
    summary: true
    type: Identifier
    array: true
  photo:
    type: Attachment
    array: true
  link:
    summary: true
    modifier: true
    required:
    - other
    - type
    type: BackboneElement
    array: true
    elements:
      other:
        refers:
        - http://hl7.org/fhir/StructureDefinition/Patient
        - http://hl7.org/fhir/StructureDefinition/RelatedPerson
        scalar: true
        summary: true
        type: Reference
      type:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/link-type
          strength: required
          codesystems:
          - http://hl7.org/fhir/link-type
        scalar: true
        summary: true
        type: code
  birthDate:
    scalar: true
    summary: true
    type: date
  multipleBirthBoolean:
    scalar: true
    type: boolean
    choiceOf: multipleBirth
  communication:
    required:
    - language
    type: BackboneElement
    array: true
    elements:
      language:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/languages
          strength: preferred
        scalar: true
        type: CodeableConcept
      preferred:
        scalar: true
        type: boolean
  telecom:
    summary: true
    type: ContactPoint
    array: true
  active:
    scalar: true
    summary: true
    modifier: true
    type: boolean
  deceased:
    choices:
    - deceasedBoolean
    - deceasedDateTime
    scalar: true
  generalPractitioner:
    refers:
    - http://hl7.org/fhir/StructureDefinition/Organization
    - http://hl7.org/fhir/StructureDefinition/Practitioner
    - http://hl7.org/fhir/StructureDefinition/PractitionerRole
    type: Reference
    array: true
  contact:
    constraints:
      pat-1:
        human: SHALL at least contain a contact's details or a reference to an organization
        severity: error
        expression: name.exists() or telecom.exists() or address.exists() or organization.exists()
    type: BackboneElement
    array: true
    elements:
      relationship:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/patient-contactrelationship
          strength: extensible
        type: CodeableConcept
        array: true
      name:
        scalar: true
        type: HumanName
      telecom:
        type: ContactPoint
        array: true
      address:
        scalar: true
        type: Address
      gender:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/administrative-gender
          strength: required
          codesystems:
          - http://hl7.org/fhir/administrative-gender
        scalar: true
        type: code
      organization:
        refers:
        - http://hl7.org/fhir/StructureDefinition/Organization
        scalar: true
        type: Reference
      period:
        scalar: true
        type: Period
  multipleBirthInteger:
    scalar: true
    type: integer
    choiceOf: multipleBirth

Resource example that conforms to schema mentioned earlier:

resourceType: Patient
gender: male
resourceType: Patient
name:
  - text: John Smith

Resource example that didn't conform to schema mentioned earlier

resourceType: Patient
gender:
  - male
resourceType: Patient
name:
  text: John Smith

Cardinality

There are 2 properties controlling element cardinality:

  • min
  • max

Cardinality defines the minimum and maximum number of elements in an array. These properties are allowed only if the shape is set to 'array'.

Absent cardinality property means this cardinality is not restricted. The schema may contain only min or max properties, or it may omit both.

Example

Schema

url: http://example.org/StructureDefinition/patient-minmax
base: http://hl7.org/fhir/StructureDefinition/Patient
type: Patient
derivation: constraint
elements:
  name:
    min: 2
    max: 3

Valid resources

resourceType: Patient
name:
  - text: James
  - text: Mary
meta:
  profile:
    - http://example.org/StructureDefinition/patient-minmax
resourceType: Patient
name:
  - text: James
  - text: Mary
  - text: Robert
meta:
  profile:
    - http://example.org/StructureDefinition/patient-minmax

Invalid resources:

resourceType: Patient
name:
  - text: James
meta:
  profile:
    - http://example.org/StructureDefinition/patient-minmax
resourceType: Patient
name:
  - text: James
  - text: Mary
  - text: Robert
  - text: Patricia
meta:
  profile:
    - http://example.org/StructureDefinition/patient-minmax

Choice type

In FHIR, polymorphic types are used to allow values of different types for specific fields.

resourceType: Patient
multipleBirthBoolean: true
resourceType: Patient
multipleBirthInteger: 2

In the example provided above, multipleBirth[x] is a choice type element, the value of which can either be of the boolean type (multipleBirthBoolean) or the integer type (multipleBirthInteger).

The concurrent presence of the multipleBirthBoolean field and the multipleBirthInteger field in the data is not allowed.

There are 2 properties controlling that polymorphism:

  • choices
  • choiceOf

choices

This property is intended for the enumeration of available polymorphic type elements.

Example

url: http://example.org/StructureDefinition/patient-choice-type
base: http://hl7.org/fhir/StructureDefinition/Patient
derivation: constraint
elements:
  multipleBirth:
    choices:
      - multipleBirthBoolean
      - multipleBirthInteger
  multipleBirthBoolean:
    choiceOf: multipleBirth
    type: boolean
  multipleBirthInteger:
    type: integer
    choiceOf: multipleBirth

choiceOf

Every concrete polymorphic type element specifies its polymorphic name under the choiceOf property.

Example

url: http://example.org/StructureDefinition/patient-choice-type
base: http://hl7.org/fhir/StructureDefinition/Patient
derivation: constraint
elements:
  multipleBirth:
    choices:
      - multipleBirthBoolean
      - multipleBirthInteger
  multipleBirthBoolean:
    choiceOf: multipleBirth
    type: boolean
  multipleBirthInteger:
    type: integer
    choiceOf: multipleBirth

Valid resources:

resourceType: Patient
meta:
  profile:
    - http://example.org/StructureDefinition/patient-choice-type
multipleBirthBoolean: true
resourceType: Patient
meta:
  profile:
    - http://example.org/StructureDefinition/patient-choice-type
multipleBirthInteger: 3

Invalid resources:

resourceType: Patient
meta:
  profile:
    - http://example.org/StructureDefinition/patient-choice-type
multipleBirthBoolean: true
multipleBirthInteger: 3
resourceType: Patient
meta:
  profile:
    - http://example.org/StructureDefinition/patient-choice-type
multipleBirthString: "3"
resourceType: Patient
meta:
  profile:
    - http://example.org/StructureDefinition/patient-choice-type
multipleBirth: true
resourceType: Patient
meta:
  profile:
    - http://example.org/StructureDefinition/patient-choice-type
multipleBirth: 3

Requires and exclusions

There are 2 elements controlling required and excluded elements:

  • required
  • excluded

The required property lists all subelements which shall be present. The excluded property lists all subelements which shall be absent.

Example

Schema

url: http://example.org/StructureDefinition/patient-minmax
base: http://hl7.org/fhir/StructureDefinition/Patient
type: Patient
derivation: constraint
required:
  - birthDate
excluded:
  - gender

Valid resources

resourceType: Patient
birthDate: "2000-01-01"
meta:
  profile:
    - http://example.org/StructureDefinition/patient-minmax
resourceType: Patient
birthDate: "2000-01-01"
active: true
meta:
  profile:
    - http://example.org/StructureDefinition/patient-minmax

Invalid resources

resourceType: Patient
active: true
meta:
  profile:
    - http://example.org/StructureDefinition/patient-minmax
resourceType: Patient
gender: other
meta:
  profile:
    - http://example.org/StructureDefinition/patient-minmax
resourceType: Patient
birthDate: "2000-01-01"
gender: other
meta:
  profile:
    - http://example.org/StructureDefinition/patient-minmax

Type reference

There are 2 properties specifying type references:

  • type
  • elementReference

These two properties are mutually exclusive.

Type reference is either a FHIR type name or canonical URL of the FHIR type.

Base type

The type property specified base type of the element. Data is accepted if both conditions are met:

  • Data is accepted when validated against referred type
  • Data is accepted by all other conditions on element

Example

Schema

id: Patient
url: http://hl7.org/fhir/StructureDefinition/Patient
package-meta:
  name: hl7.fhir.r4.core
  version: 4.0.1
  path: "/tmp/lw-fhir-schema-repository/hl7.fhir.r4.core#4.0.1"
base: http://hl7.org/fhir/StructureDefinition/DomainResource
kind: resource
type: Patient
derivation: specialization
elements:
  deceasedBoolean:
    scalar: true
    summary: true
    modifier: true
    type: boolean
    choiceOf: deceased
  maritalStatus:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/marital-status
      strength: extensible
    scalar: true
    type: CodeableConcept
  deceasedDateTime:
    scalar: true
    summary: true
    modifier: true
    type: dateTime
    choiceOf: deceased
  managingOrganization:
    refers:
      - http://hl7.org/fhir/StructureDefinition/Organization
    scalar: true
    summary: true
    type: Reference
  gender:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/administrative-gender
      strength: required
      codesystems:
        - http://hl7.org/fhir/administrative-gender
    type: code
    scalar: true
    summary: true
  multipleBirth:
    choices:
      - multipleBirthBoolean
      - multipleBirthInteger
    scalar: true
  name:
    summary: true
    type: HumanName
    array: true
  address:
    summary: true
    type: Address
    array: true
  identifier:
    summary: true
    type: Identifier
    array: true
  photo:
    type: Attachment
    array: true
  link:
    summary: true
    modifier: true
    required:
      - other
      - type
    type: BackboneElement
    array: true
    elements:
      other:
        refers:
          - http://hl7.org/fhir/StructureDefinition/Patient
          - http://hl7.org/fhir/StructureDefinition/RelatedPerson
        scalar: true
        summary: true
        type: Reference
      type:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/link-type
          strength: required
          codesystems:
            - http://hl7.org/fhir/link-type
        scalar: true
        summary: true
        type: code
  birthDate:
    scalar: true
    summary: true
    type: date
  multipleBirthBoolean:
    scalar: true
    type: boolean
    choiceOf: multipleBirth
  communication:
    required:
      - language
    type: BackboneElement
    array: true
    elements:
      language:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/languages
          strength: preferred
        scalar: true
        type: CodeableConcept
      preferred:
        scalar: true
        type: boolean
  telecom:
    summary: true
    type: ContactPoint
    array: true
  active:
    scalar: true
    summary: true
    modifier: true
    type: boolean
  deceased:
    choices:
      - deceasedBoolean
      - deceasedDateTime
    scalar: true
  generalPractitioner:
    refers:
      - http://hl7.org/fhir/StructureDefinition/Organization
      - http://hl7.org/fhir/StructureDefinition/Practitioner
      - http://hl7.org/fhir/StructureDefinition/PractitionerRole
    type: Reference
    array: true
  contact:
    constraints:
      pat-1:
        human: SHALL at least contain a contact's details or a reference to an organization
        severity: error
        expression: name.exists() or telecom.exists() or address.exists() or organization.exists()
    type: BackboneElement
    array: true
    elements:
      relationship:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/patient-contactrelationship
          strength: extensible
        type: CodeableConcept
        array: true
      name:
        scalar: true
        type: HumanName
      telecom:
        type: ContactPoint
        array: true
      address:
        scalar: true
        type: Address
      gender:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/administrative-gender
          strength: required
          codesystems:
            - http://hl7.org/fhir/administrative-gender
        scalar: true
        type: code
      organization:
        refers:
          - http://hl7.org/fhir/StructureDefinition/Organization
        scalar: true
        type: Reference
      period:
        scalar: true
        type: Period
  multipleBirthInteger:
    scalar: true
    type: integer
    choiceOf: multipleBirth
elements:
  a:
    type: string
    array: true
    max: 1
  b:
    type: http://hl7.org/fhir/StructureDefinition/string
    array: true
    max: 1

Valid resources

resourceType: Patient
gender: other
resourceType: Patient
name:
  - text: James

Invalid resources

resourceType: Patient
gender: 2
resourceType: Patient
name:
  - James
resourceType: Patient
gender:
  text: James
resourceType: Patient
name:
  - 2

Element reference syntax

Element reference is an array of the following format:

  • First element is a type reference
  • Other elements are a path in FHIRSchema

Example

Schema

url: http://example.org/abc
elements:
  a:
    elements:
      b:
        type: string

Element reference referring the b element

[http://example.org/abc, elements, a, elements, b]

Element reference

Data is accepted if both conditions are met:

  • Data is accepted when validated against schema for referred element
  • Data is accepted by all other conditions on element

Element reference is useful for defining recursive structures (e.g. Questionnaire.item)

Example

Schema

url: http://hl7.org/fhir/StructureDefinition/Questionnaire
constraints:
  que-2:
    human: The link ids for groups and questions must be unique within the questionnaire
    severity: error
    expression: descendants().linkId.isDistinct()
  que-0:
    human: Name should be usable as an identifier for the module by machine processing applications such as code generation
    severity: warning
    expression: name.matches('[A-Z]([A-Za-z0-9_]){0,254}')
package-meta:
  name: hl7.fhir.r4.core
  version: 4.0.1
  path: /tmp/lw-fhir-schema-repository/hl7.fhir.r4.core#4.0.1
id: Questionnaire
base: http://hl7.org/fhir/StructureDefinition/DomainResource
kind: resource
required:
  - status
type: Questionnaire
elements:
  url:
    scalar: true
    summary: true
    type: uri
  derivedFrom:
    refers:
      - http://hl7.org/fhir/StructureDefinition/Questionnaire
    type: canonical
    array: true
  experimental:
    scalar: true
    summary: true
    type: boolean
  effectivePeriod:
    scalar: true
    summary: true
    type: Period
  approvalDate:
    scalar: true
    type: date
  name:
    scalar: true
    summary: true
    type: string
  status:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/publication-status
      strength: required
      codesystems:
        - http://hl7.org/fhir/publication-status
    scalar: true
    summary: true
    modifier: true
    type: code
  identifier:
    summary: true
    type: Identifier
    array: true
  item:
    constraints:
      que-6:
        human: Required and repeat aren't permitted for display items
        severity: error
        expression: type!='display' or (required.empty() and repeats.empty())
      que-3:
        human: Display items cannot have a "code" asserted
        severity: error
        expression: type!='display' or code.empty()
      que-4:
        human: A question cannot have both answerOption and answerValueSet
        severity: error
        expression: answerOption.empty() or answerValueSet.empty()
      que-8:
        human: Initial values can't be specified for groups or display items
        severity: error
        expression: (type!='group' and type!='display') or initial.empty()
      que-13:
        human: Can only have multiple initial values for repeating items
        severity: error
        expression: repeats=true or initial.count() <= 1
      que-12:
        human: If there are more than one enableWhen, enableBehavior must be specified
        severity: error
        expression: enableWhen.count() > 2 implies enableBehavior.exists()
      que-11:
        human: If one or more answerOption is present, initial[x] must be missing
        severity: error
        expression: answerOption.empty() or initial.empty()
      que-9:
        human: Read-only can't be specified for "display" items
        severity: error
        expression: type!='display' or readOnly.empty()
      que-1:
        human: Group items must have nested items, display items cannot have nested items
        severity: error
        expression: (type='group' implies item.empty().not()) and (type.trace('type')='display' implies item.trace('item').empty())
      que-10:
        human: Maximum length can only be declared for simple question types
        severity: error
        expression: (type in ('boolean' | 'decimal' | 'integer' | 'string' | 'text' | 'url' | 'open-choice')) or maxLength.empty()
      que-5:
        human: Only 'choice' and 'open-choice' items can have answerValueSet
        severity: error
        expression: (type ='choice' or type = 'open-choice' or type = 'decimal' or type = 'integer' or type = 'date' or type = 'dateTime' or type = 'time' or type = 'string' or type = 'quantity') or (answerValueSet.empty() and answerOption.empty())
    required:
      - linkId
      - type
    type: BackboneElement
    array: true
    elements:
      answerValueSet:
        refers:
          - http://hl7.org/fhir/StructureDefinition/ValueSet
        scalar: true
        type: canonical
      repeats:
        scalar: true
        type: boolean
      prefix:
        scalar: true
        type: string
      answerOption:
        required:
          - value
          - value
          - value
          - value
          - value
          - value
        type: BackboneElement
        array: true
        elements:
          valueInteger:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: integer
            choiceOf: value
          value:
            choices:
              - valueInteger
              - valueDate
              - valueTime
              - valueString
              - valueCoding
              - valueReference
            scalar: true
          valueDate:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: date
            choiceOf: value
          valueTime:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: time
            choiceOf: value
          valueString:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: string
            choiceOf: value
          valueCoding:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: Coding
            choiceOf: value
          valueReference:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            refers:
              - http://hl7.org/fhir/StructureDefinition/Resource
            scalar: true
            required-element: true
            type: Reference
            choiceOf: value
          initialSelected:
            scalar: true
            type: boolean
      maxLength:
        scalar: true
        type: integer
      initial:
        required:
          - value
          - value
          - value
          - value
          - value
          - value
          - value
          - value
          - value
          - value
          - value
          - value
        type: BackboneElement
        array: true
        elements:
          valueCoding:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: Coding
            choiceOf: value
          valueUri:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: uri
            choiceOf: value
          valueString:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: string
            choiceOf: value
          valueReference:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            refers:
              - http://hl7.org/fhir/StructureDefinition/Resource
            scalar: true
            required-element: true
            type: Reference
            choiceOf: value
          valueDecimal:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: decimal
            choiceOf: value
          valueAttachment:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: Attachment
            choiceOf: value
          valueDateTime:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: dateTime
            choiceOf: value
          value:
            choices:
              - valueBoolean
              - valueDecimal
              - valueInteger
              - valueDate
              - valueDateTime
              - valueTime
              - valueString
              - valueUri
              - valueAttachment
              - valueCoding
              - valueQuantity
              - valueReference
            scalar: true
          valueBoolean:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: boolean
            choiceOf: value
          valueDate:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: date
            choiceOf: value
          valueTime:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: time
            choiceOf: value
          valueQuantity:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: Quantity
            choiceOf: value
          valueInteger:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: integer
            choiceOf: value
      enableWhen:
        constraints:
          que-7:
            human: If the operator is 'exists', the value must be a boolean
            severity: error
            expression: operator = 'exists' implies (answer is Boolean)
        modifier: true
        required:
          - question
          - operator
          - answer
          - answer
          - answer
          - answer
          - answer
          - answer
          - answer
          - answer
          - answer
          - answer
        type: BackboneElement
        array: true
        elements:
          answerReference:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            refers:
              - http://hl7.org/fhir/StructureDefinition/Resource
            scalar: true
            required-element: true
            type: Reference
            choiceOf: answer
          operator:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-enable-operator
              strength: required
              codesystems:
                - http://hl7.org/fhir/questionnaire-enable-operator
            scalar: true
            type: code
          answerDate:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: date
            choiceOf: answer
          answerTime:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: time
            choiceOf: answer
          answerString:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: string
            choiceOf: answer
          answerCoding:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: Coding
            choiceOf: answer
          question:
            scalar: true
            type: string
          answerInteger:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: integer
            choiceOf: answer
          answerQuantity:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: Quantity
            choiceOf: answer
          answerDateTime:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: dateTime
            choiceOf: answer
          answerBoolean:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: boolean
            choiceOf: answer
          answerDecimal:
            binding:
              valueSet: http://hl7.org/fhir/ValueSet/questionnaire-answers
              strength: example
            scalar: true
            required-element: true
            type: decimal
            choiceOf: answer
          answer:
            choices:
              - answerBoolean
              - answerDecimal
              - answerInteger
              - answerDate
              - answerDateTime
              - answerTime
              - answerString
              - answerCoding
              - answerQuantity
              - answerReference
            scalar: true
      text:
        scalar: true
        type: string
      item:
        elementReference:
          - http://hl7.org/fhir/StructureDefinition/Questionnaire
          - elements
          - item
        array: true
      enableBehavior:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/questionnaire-enable-behavior
          strength: required
          codesystems:
            - http://hl7.org/fhir/questionnaire-enable-behavior
        scalar: true
        type: code
      definition:
        scalar: true
        type: uri
      readOnly:
        scalar: true
        type: boolean
      required:
        scalar: true
        type: boolean
      type:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/item-type
          strength: required
          codesystems:
            - http://hl7.org/fhir/item-type
        scalar: true
        type: code
      linkId:
        scalar: true
        type: string
      code:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/questionnaire-questions
          strength: example
        type: Coding
        array: true
  jurisdiction:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/jurisdiction
      strength: extensible
    summary: true
    type: CodeableConcept
    array: true
  title:
    scalar: true
    summary: true
    type: string
  copyright:
    scalar: true
    type: markdown
  publisher:
    scalar: true
    summary: true
    type: string
  version:
    scalar: true
    summary: true
    type: string
  date:
    scalar: true
    summary: true
    type: dateTime
  subjectType:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/resource-types
      strength: required
      codesystems:
        - http://hl7.org/fhir/resource-types
    summary: true
    type: code
    array: true
  useContext:
    summary: true
    type: UsageContext
    array: true
  lastReviewDate:
    scalar: true
    type: date
  code:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/questionnaire-questions
      strength: example
    summary: true
    type: Coding
    array: true
  contact:
    summary: true
    type: ContactDetail
    array: true
  description:
    scalar: true
    type: markdown
  purpose:
    scalar: true
    type: markdown
derivation: specialization

Valid resources:

resourceType: Questionnaire
status: draft
item:
  - type: display
    linkId: q-1
resourceType: Questionnaire
status: draft
item:
  - item:
      - type: display
        linkId: q-2
    type: group
    linkId: q-1
resourceType: Questionnaire
status: draft
item:
  - item:
      - item:
          - item:
              - type: display
                linkId: q-4
            linkId: q-3
            type: group
        linkId: q-2
        type: group
    linkId: q-1
    type: group

Invalid resources:

resourceType: Questionnaire
status: draft
item:
  - item:
      - wrongType
    type: group
    linkId: q-1
resourceType: Questionnaire
status: draft
item:
  - item:
      - item:
          - nonExistentField: abc
            linkId: q-3
            type: group
        linkId: q-2
        type: group
    linkId: q-1
    type: group

Nested elements

The elements property define nested element constraints. Syntactically it is an object, with string keys and Element values. Semantically it defines behavior of the corresponding fields in data.

Example

Schema

id: Patient
url: http://hl7.org/fhir/StructureDefinition/Patient
package-meta:
  name: hl7.fhir.r4.core
  version: 4.0.1
  path: "/tmp/lw-fhir-schema-repository/hl7.fhir.r4.core#4.0.1"
base: http://hl7.org/fhir/StructureDefinition/DomainResource
kind: resource
type: Patient
derivation: specialization
elements:
  deceasedBoolean:
    scalar: true
    summary: true
    modifier: true
    type: boolean
    choiceOf: deceased
  maritalStatus:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/marital-status
      strength: extensible
    scalar: true
    type: CodeableConcept
  deceasedDateTime:
    scalar: true
    summary: true
    modifier: true
    type: dateTime
    choiceOf: deceased
  managingOrganization:
    refers:
      - http://hl7.org/fhir/StructureDefinition/Organization
    scalar: true
    summary: true
    type: Reference
  gender:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/administrative-gender
      strength: required
      codesystems:
        - http://hl7.org/fhir/administrative-gender
    type: code
    scalar: true
    summary: true
  multipleBirth:
    choices:
      - multipleBirthBoolean
      - multipleBirthInteger
    scalar: true
  name:
    summary: true
    type: HumanName
    array: true
  address:
    summary: true
    type: Address
    array: true
  identifier:
    summary: true
    type: Identifier
    array: true
  photo:
    type: Attachment
    array: true
  link:
    summary: true
    modifier: true
    required:
      - other
      - type
    type: BackboneElement
    array: true
    elements:
      other:
        refers:
          - http://hl7.org/fhir/StructureDefinition/Patient
          - http://hl7.org/fhir/StructureDefinition/RelatedPerson
        scalar: true
        summary: true
        type: Reference
      type:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/link-type
          strength: required
          codesystems:
            - http://hl7.org/fhir/link-type
        scalar: true
        summary: true
        type: code
  birthDate:
    scalar: true
    summary: true
    type: date
  multipleBirthBoolean:
    scalar: true
    type: boolean
    choiceOf: multipleBirth
  communication:
    required:
      - language
    type: BackboneElement
    array: true
    elements:
      language:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/languages
          strength: preferred
        scalar: true
        type: CodeableConcept
      preferred:
        scalar: true
        type: boolean
  telecom:
    summary: true
    type: ContactPoint
    array: true
  active:
    scalar: true
    summary: true
    modifier: true
    type: boolean
  deceased:
    choices:
      - deceasedBoolean
      - deceasedDateTime
    scalar: true
  generalPractitioner:
    refers:
      - http://hl7.org/fhir/StructureDefinition/Organization
      - http://hl7.org/fhir/StructureDefinition/Practitioner
      - http://hl7.org/fhir/StructureDefinition/PractitionerRole
    type: Reference
    array: true
  contact:
    constraints:
      pat-1:
        human: SHALL at least contain a contact's details or a reference to an organization
        severity: error
        expression: name.exists() or telecom.exists() or address.exists() or organization.exists()
    type: BackboneElement
    array: true
    elements:
      relationship:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/patient-contactrelationship
          strength: extensible
        type: CodeableConcept
        array: true
      name:
        scalar: true
        type: HumanName
      telecom:
        type: ContactPoint
        array: true
      address:
        scalar: true
        type: Address
      gender:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/administrative-gender
          strength: required
          codesystems:
            - http://hl7.org/fhir/administrative-gender
        scalar: true
        type: code
      organization:
        refers:
          - http://hl7.org/fhir/StructureDefinition/Organization
        scalar: true
        type: Reference
      period:
        scalar: true
        type: Period
  multipleBirthInteger:
    scalar: true
    type: integer
    choiceOf: multipleBirth

Valid resource

resourceType: Patient
link: 
  - other: 
      reference: http://example.org/patient-path
      type: Patient
    type: refer

Invalid resource

resourceType: Patient
link: 
  - unexisting: true

Terminology binding

Syntax

  • valueSet (string)
  • strength (string)

FHIRSchema terminology binding follows FHIR terminology binding. Both valueSet and strength properties shall be specified.

The valueSet property is a canonical URL referring to the ValueSet to which the codes in the data element value are bound. The strength property specifies FHIR ValueSet binding strength. Only required bindings are validated.

Example

Schema

id: Patient
url: http://hl7.org/fhir/StructureDefinition/Patient
package-meta:
  name: hl7.fhir.r4.core
  version: 4.0.1
  path: "/tmp/lw-fhir-schema-repository/hl7.fhir.r4.core#4.0.1"
base: http://hl7.org/fhir/StructureDefinition/DomainResource
kind: resource
type: Patient
derivation: specialization
elements:
  deceasedBoolean:
    scalar: true
    summary: true
    modifier: true
    type: boolean
    choiceOf: deceased
  maritalStatus:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/marital-status
      strength: extensible
    scalar: true
    type: CodeableConcept
  deceasedDateTime:
    scalar: true
    summary: true
    modifier: true
    type: dateTime
    choiceOf: deceased
  managingOrganization:
    refers:
      - http://hl7.org/fhir/StructureDefinition/Organization
    scalar: true
    summary: true
    type: Reference
  gender:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/administrative-gender
      strength: required
      codesystems:
        - http://hl7.org/fhir/administrative-gender
    type: code
    scalar: true
    summary: true
  multipleBirth:
    choices:
      - multipleBirthBoolean
      - multipleBirthInteger
    scalar: true
  name:
    summary: true
    type: HumanName
    array: true
  address:
    summary: true
    type: Address
    array: true
  identifier:
    summary: true
    type: Identifier
    array: true
  photo:
    type: Attachment
    array: true
  link:
    summary: true
    modifier: true
    required:
      - other
      - type
    type: BackboneElement
    array: true
    elements:
      other:
        refers:
          - http://hl7.org/fhir/StructureDefinition/Patient
          - http://hl7.org/fhir/StructureDefinition/RelatedPerson
        scalar: true
        summary: true
        type: Reference
      type:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/link-type
          strength: required
          codesystems:
            - http://hl7.org/fhir/link-type
        scalar: true
        summary: true
        type: code
  birthDate:
    scalar: true
    summary: true
    type: date
  multipleBirthBoolean:
    scalar: true
    type: boolean
    choiceOf: multipleBirth
  communication:
    required:
      - language
    type: BackboneElement
    array: true
    elements:
      language:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/languages
          strength: preferred
        scalar: true
        type: CodeableConcept
      preferred:
        scalar: true
        type: boolean
  telecom:
    summary: true
    type: ContactPoint
    array: true
  active:
    scalar: true
    summary: true
    modifier: true
    type: boolean
  deceased:
    choices:
      - deceasedBoolean
      - deceasedDateTime
    scalar: true
  generalPractitioner:
    refers:
      - http://hl7.org/fhir/StructureDefinition/Organization
      - http://hl7.org/fhir/StructureDefinition/Practitioner
      - http://hl7.org/fhir/StructureDefinition/PractitionerRole
    type: Reference
    array: true
  contact:
    constraints:
      pat-1:
        human: SHALL at least contain a contact's details or a reference to an organization
        severity: error
        expression: name.exists() or telecom.exists() or address.exists() or organization.exists()
    type: BackboneElement
    array: true
    elements:
      relationship:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/patient-contactrelationship
          strength: extensible
        type: CodeableConcept
        array: true
      name:
        scalar: true
        type: HumanName
      telecom:
        type: ContactPoint
        array: true
      address:
        scalar: true
        type: Address
      gender:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/administrative-gender
          strength: required
          codesystems:
            - http://hl7.org/fhir/administrative-gender
        scalar: true
        type: code
      organization:
        refers:
          - http://hl7.org/fhir/StructureDefinition/Organization
        scalar: true
        type: Reference
      period:
        scalar: true
        type: Period
  multipleBirthInteger:
    scalar: true
    type: integer
    choiceOf: multipleBirth

Note: there is a codesystems property in expanded view of the example schema: it is a technical field generated by StructureDefinition to FHIRSchema conversion, this field speeds up schema loading, but is irrelevant to writing new schemas.

Valid resource:

resourceType: Patient
gender: other

Invalid resource:

resourceType: Patient
gender: something-not-in-the-valueset

Reference target

The refers property lists allows reference targets. A reference data element is accepted only if it refers to one of the allowed here types. A target can be either resource type or canonical URL for this resource type.

Example

Schema:

id: Patient
url: http://hl7.org/fhir/StructureDefinition/Patient
package-meta:
  name: hl7.fhir.r4.core
  version: 4.0.1
  path: "/tmp/lw-fhir-schema-repository/hl7.fhir.r4.core#4.0.1"
base: http://hl7.org/fhir/StructureDefinition/DomainResource
kind: resource
type: Patient
derivation: specialization
elements:
  deceasedBoolean:
    scalar: true
    summary: true
    modifier: true
    type: boolean
    choiceOf: deceased
  maritalStatus:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/marital-status
      strength: extensible
    scalar: true
    type: CodeableConcept
  deceasedDateTime:
    scalar: true
    summary: true
    modifier: true
    type: dateTime
    choiceOf: deceased
  managingOrganization:
    refers:
      - http://hl7.org/fhir/StructureDefinition/Organization
    scalar: true
    summary: true
    type: Reference
  gender:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/administrative-gender
      strength: required
      codesystems:
        - http://hl7.org/fhir/administrative-gender
    type: code
    scalar: true
    summary: true
  multipleBirth:
    choices:
      - multipleBirthBoolean
      - multipleBirthInteger
    scalar: true
  name:
    summary: true
    type: HumanName
    array: true
  address:
    summary: true
    type: Address
    array: true
  identifier:
    summary: true
    type: Identifier
    array: true
  photo:
    type: Attachment
    array: true
  link:
    summary: true
    modifier: true
    required:
      - other
      - type
    type: BackboneElement
    array: true
    elements:
      other:
        refers:
          - http://hl7.org/fhir/StructureDefinition/Patient
          - http://hl7.org/fhir/StructureDefinition/RelatedPerson
        scalar: true
        summary: true
        type: Reference
      type:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/link-type
          strength: required
          codesystems:
            - http://hl7.org/fhir/link-type
        scalar: true
        summary: true
        type: code
  birthDate:
    scalar: true
    summary: true
    type: date
  multipleBirthBoolean:
    scalar: true
    type: boolean
    choiceOf: multipleBirth
  communication:
    required:
      - language
    type: BackboneElement
    array: true
    elements:
      language:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/languages
          strength: preferred
        scalar: true
        type: CodeableConcept
      preferred:
        scalar: true
        type: boolean
  telecom:
    summary: true
    type: ContactPoint
    array: true
  active:
    scalar: true
    summary: true
    modifier: true
    type: boolean
  deceased:
    choices:
      - deceasedBoolean
      - deceasedDateTime
    scalar: true
  generalPractitioner:
    refers:
      - http://hl7.org/fhir/StructureDefinition/Organization
      - http://hl7.org/fhir/StructureDefinition/Practitioner
      - http://hl7.org/fhir/StructureDefinition/PractitionerRole
    type: Reference
    array: true
  contact:
    constraints:
      pat-1:
        human: SHALL at least contain a contact's details or a reference to an organization
        severity: error
        expression: name.exists() or telecom.exists() or address.exists() or organization.exists()
    type: BackboneElement
    array: true
    elements:
      relationship:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/patient-contactrelationship
          strength: extensible
        type: CodeableConcept
        array: true
      name:
        scalar: true
        type: HumanName
      telecom:
        type: ContactPoint
        array: true
      address:
        scalar: true
        type: Address
      gender:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/administrative-gender
          strength: required
          codesystems:
            - http://hl7.org/fhir/administrative-gender
        scalar: true
        type: code
      organization:
        refers:
          - http://hl7.org/fhir/StructureDefinition/Organization
        scalar: true
        type: Reference
      period:
        scalar: true
        type: Period
  multipleBirthInteger:
    scalar: true
    type: integer
    choiceOf: multipleBirth

Valid resources:

resourceType: Patient
generalPractitioner:
  - reference: Organization/organization-1
resourceType: Patient
generalPractitioner:
  - reference: Practitioner/practitioner-1
  - reference: Organization/organization-1
resourceType: Patient
generalPractitioner:
  - reference: Practitioner/practitioner-1

Invalid resources:

resourceType: Patient
generalPractitioner:
  - reference: Patient/patient-1
resourceType: Patient
generalPractitioner:
  - reference: Organization/organization-1
  - reference: Patient/patient-1

Pattern matching

There are 2 properties to define elements that match constant values:

  • fixed: a value that must match the value of element;
  • pattern: a value that specifies the entries or items that an element must contain.

Example

Schema with fixed element

url:  http://example.com/Patient/patient
base: http://hl7.org/fhir/StructureDefinition/Patient
type: Patient
name: Patient-fixed
elements:
  gender:
    type: code
    fixed: male
  name:
    type: HumanName
    fixed:
      - family: Smith

Valid resources

meta:
  profile: 
     - http://example.com/Patient/patient|1.0.0
resourceType: Patient
gender: male
name:
  - family: Smith

Invalid resources

meta:
  profile: 
    - http://example.com/Patient/patient|1.0.0
resourceType: Patient
gender: male
name:
  - family: Smith
    given: John
meta:
  profile: 
    - http://example.com/Patient/patient|1.0.0
resourceType: Patient
gender: female
name:
  - family: Smith
meta:
  profile: 
    - http://example.com/Patient/patient|1.0.0
resourceType: Patient
gender: male
name:
  - family: Smith
    given: John
meta:
  profile: 
    - http://example.com/Patient/patient|1.0.0
resourceType: Patient
gender: male
name:
  - family: Smith
  - family: Gray

Schema with pattern element

url:  http://example.com/Patient/patient
base: http://hl7.org/fhir/StructureDefinition/Patient
type: Patient
name: Patient-pattern
elements:
  gender: 
    type: code
    pattern: male
  name:
    type: HumanName
    pattern:
      - family: Smith

Valid resources

meta:
  profile: 
    - http://example.com/Patient/patient|1.0.0
resourceType: Patient
gender: male
name:
  - family: Smith
meta:
  profile: 
    - http://example.com/Patient/patient|1.0.0
resourceType: Patient
gender: male
name:
  - family: Smith
    given: John
meta:
  profile: 
    - http://example.com/Patient/patient|1.0.0
resourceType: Patient
gender: male
name:
  - family: Smith
  - family: Gray

Invalid resources

meta:
  profile: 
    - http://example.com/Patient/patient|1.0.0
resourceType: Patient
gender: female
name:
  - family: Smith
meta:
  profile: 
    - http://example.com/Patient/patient|1.0.0
resourceType: Patient
gender: male
name:
  - family: Gray

Informational

These properties do not affect validation, but they provide additional information about element.

The modifier property mirrors the ElementDefinition.isModifier FHIR property. The modifier element changes the interpretation of the resource.

The mustSupport property mirrors the ElementDefinition.mustSupport FHIR property. The mustSupport element must be supported by an implementation.

The summary property mirrors the ElementDefinition.isSummary FHIR property. The summary element should be included in FHIR Search in summary mode.

Constraint

Constraint is a component of the FHIR Schema that specifies FHIRPath constraints.

Syntax

Constraint ID property:

  • <your-constraint-id> (string)

    Expression property:

    • expression (string)

    Human property:

    • human (string)

    Severity property:

    • severity (string: error | warning | guideline)

Constraint ID

A constraint ID must be unique within the constraints declaration scope. It serves as an identifier for the constraint, aiding in error identification by logging which constraint was violated.

Expression

A FHIRPath expression. For technical details, please refer to the ANSI FHIRPath specification.

Examples

Example of a constraint on the contact attribute in the FHIR R4 Patient schema:

id: Patient
url: http://hl7.org/fhir/StructureDefinition/Patient
package-meta:
  name: hl7.fhir.r4.core
  version: 4.0.1
  path: "/tmp/lw-fhir-schema-repository/hl7.fhir.r4.core#4.0.1"
base: http://hl7.org/fhir/StructureDefinition/DomainResource
kind: resource
type: Patient
derivation: specialization
elements:
  deceasedBoolean:
    scalar: true
    summary: true
    modifier: true
    type: boolean
    choiceOf: deceased
  maritalStatus:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/marital-status
      strength: extensible
    scalar: true
    type: CodeableConcept
  deceasedDateTime:
    scalar: true
    summary: true
    modifier: true
    type: dateTime
    choiceOf: deceased
  managingOrganization:
    refers:
    - http://hl7.org/fhir/StructureDefinition/Organization
    scalar: true
    summary: true
    type: Reference
 gender:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/administrative-gender
      strength: required
      codesystems:
      - http://hl7.org/fhir/administrative-gender
   type: code
   scalar: true
    summary: true
  multipleBirth:
    choices:
    - multipleBirthBoolean
    - multipleBirthInteger
    scalar: true
 name:
    summary: true
   type: HumanName
   array: true
  address:
    summary: true
    type: Address
    array: true
  identifier:
    summary: true
    type: Identifier
    array: true
  photo:
    type: Attachment
    array: true
  link:
    summary: true
    modifier: true
    required:
    - other
    - type
    type: BackboneElement
    array: true
    elements:
      other:
        refers:
        - http://hl7.org/fhir/StructureDefinition/Patient
        - http://hl7.org/fhir/StructureDefinition/RelatedPerson
        scalar: true
        summary: true
        type: Reference
      type:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/link-type
          strength: required
          codesystems:
          - http://hl7.org/fhir/link-type
        scalar: true
        summary: true
        type: code
  birthDate:
    scalar: true
    summary: true
    type: date
  multipleBirthBoolean:
    scalar: true
    type: boolean
    choiceOf: multipleBirth
  communication:
    required:
    - language
    type: BackboneElement
    array: true
    elements:
      language:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/languages
          strength: preferred
        scalar: true
        type: CodeableConcept
      preferred:
        scalar: true
        type: boolean
  telecom:
    summary: true
    type: ContactPoint
    array: true
  active:
    scalar: true
    summary: true
    modifier: true
    type: boolean
  deceased:
    choices:
    - deceasedBoolean
    - deceasedDateTime
    scalar: true
  generalPractitioner:
    refers:
    - http://hl7.org/fhir/StructureDefinition/Organization
    - http://hl7.org/fhir/StructureDefinition/Practitioner
    - http://hl7.org/fhir/StructureDefinition/PractitionerRole
    type: Reference
    array: true
  contact:
    constraints:
      pat-1:
        human: SHALL at least contain a contact's details or a reference to an organization
        severity: error
        expression: name.exists() or telecom.exists() or address.exists() or organization.exists()
    type: BackboneElement
    array: true
    elements:
      relationship:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/patient-contactrelationship
          strength: extensible
        type: CodeableConcept
        array: true
      name:
        scalar: true
        type: HumanName
      telecom:
        type: ContactPoint
        array: true
      address:
        scalar: true
        type: Address
      gender:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/administrative-gender
          strength: required
          codesystems:
          - http://hl7.org/fhir/administrative-gender
        scalar: true
        type: code
      organization:
        refers:
        - http://hl7.org/fhir/StructureDefinition/Organization
        scalar: true
        type: Reference
      period:
        scalar: true
        type: Period
  multipleBirthInteger:
    scalar: true
    type: integer
    choiceOf: multipleBirth

Data sample adhering to the previously mentioned schema:

resourceType: Patient
contact:
  - gender: true
    name:
      - given:
          - John
        family: Smith

Data sample not conforming to the previously mentioned schema:

resourceType: Patient
contact:
  - gender: true

Variables in Expressions

The ANSI FHIRPath specification defines two environment variables for the FHIRPath engine's evaluation context:

  • %ucum — URL for UCUM (http://unitsofmeasure.org), as per HL7 UCUM.
  • %context — The node evaluated by the engine at the start of evaluation.

FHIR extends FHIRPath with two additional variables:

  • %rootResource — the container resource for %resource
  • %resource — the resource containing the node in %context

%ucum

Holds the URL http://unitsofmeasure.org for UCUM.

%context

%context varies based on where the constraints property is defined:

Constraints at Specific Elements

For constraints in the contact element of the FHIR R4 Patient schema:

id: Patient
url: http://hl7.org/fhir/StructureDefinition/Patient
package-meta:
  name: hl7.fhir.r4.core
  version: 4.0.1
  path: "/tmp/lw-fhir-schema-repository/hl7.fhir.r4.core#4.0.1"
base: http://hl7.org/fhir/StructureDefinition/DomainResource
kind: resource
type: Patient
derivation: specialization
elements:
  deceasedBoolean:
    scalar: true
    summary: true
    modifier: true
    type: boolean
    choiceOf: deceased
  maritalStatus:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/marital-status
      strength: extensible
    scalar: true
    type: CodeableConcept
  deceasedDateTime:
    scalar: true
    summary: true
    modifier: true
    type: dateTime
    choiceOf: deceased
  managingOrganization:
    refers:
    - http://hl7.org/fhir/StructureDefinition/Organization
    scalar: true
    summary: true
    type: Reference
 gender:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/administrative-gender
      strength: required
      codesystems:
      - http://hl7.org/fhir/administrative-gender
   type: code
   scalar: true
    summary: true
  multipleBirth:
    choices:
    - multipleBirthBoolean
    - multipleBirthInteger
    scalar: true
 name:
    summary: true
   type: HumanName
   array: true
  address:
    summary: true
    type: Address
    array: true
  identifier:
    summary: true
    type: Identifier
    array: true
  photo:
    type: Attachment
    array: true
  link:
    summary: true
    modifier: true
    required:
    - other
    - type
    type: BackboneElement
    array: true
    elements:
      other:
        refers:
        - http://hl7.org/fhir/StructureDefinition/Patient
        - http://hl7.org/fhir/StructureDefinition/RelatedPerson
        scalar: true
        summary: true
        type: Reference
      type:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/link-type
          strength: required
          codesystems:
          - http://hl7.org/fhir/link-type
        scalar: true
        summary: true
        type: code
  birthDate:
    scalar: true
    summary: true
    type: date
  multipleBirthBoolean:
    scalar: true
    type: boolean
    choiceOf: multipleBirth
  communication:
    required:
    - language
    type: BackboneElement
    array: true
    elements:
      language:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/languages
          strength: preferred
        scalar: true
        type: CodeableConcept
      preferred:
        scalar: true
        type: boolean
  telecom:
    summary: true
    type: ContactPoint
    array: true
  active:
    scalar: true
    summary: true
    modifier: true
    type: boolean
  deceased:
    choices:
    - deceasedBoolean
    - deceasedDateTime
    scalar: true
  generalPractitioner:
    refers:
    - http://hl7.org/fhir/StructureDefinition/Organization
    - http://hl7.org/fhir/StructureDefinition/Practitioner
    - http://hl7.org/fhir/StructureDefinition/PractitionerRole
    type: Reference
    array: true
  contact:
    constraints:
      pat-1:
        human: SHALL at least contain a contact's details or a reference to an organization
        severity: error
        expression: name.exists() or telecom.exists() or address.exists() or organization.exists()
    type: BackboneElement
    array: true
    elements:
      relationship:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/patient-contactrelationship
          strength: extensible
        type: CodeableConcept
        array: true
      name:
        scalar: true
        type: HumanName
      telecom:
        type: ContactPoint
        array: true
      address:
        scalar: true
        type: Address
      gender:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/administrative-gender
          strength: required
          codesystems:
          - http://hl7.org/fhir/administrative-gender
        scalar: true
        type: code
      organization:
        refers:
        - http://hl7.org/fhir/StructureDefinition/Organization
        scalar: true
        type: Reference
      period:
        scalar: true
        type: Period
  multipleBirthInteger:
    scalar: true
    type: integer
    choiceOf: multipleBirth

With this data sample:

resourceType: Patient
active: true
gender: male
contact:
  - gender: true
    name:
      - given:
          - John
        family: Smith

The FHIRPath engine processes this data node:

- gender: true
  name:
    - given:
        - John
      family: Smith

Constraints at Top Level

For top-level constraints in the US Core 5.0.1 Patient schema:

url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient
constraints:
  us-core-6:
    human: Either Patient.name.given and/or Patient.name.family SHALL be present or
      a Data Absent Reason Extension SHALL be present.
    severity: error
    expression: "(name.family.exists() or name.given.exists()) xor extension.where(url='http://hl7.org/fhir/StructureDefinition/data-absent-reason').exists()"
package-meta:
  name: hl7.fhir.us.core
  version: 5.0.1
  path: "/tmp/lw-fhir-schema-repository/hl7.fhir.us.core#5.0.1"
id: us-core-patient
base: http://hl7.org/fhir/StructureDefinition/Patient
kind: resource
required:
- identifier
- name
- gender
type: Patient
elements:
  extension:
    slicing:
      slices:
        race:
          schema:
            type: Extension
          min: 0
          max: 1
          match:
            type: pattern
            value:
              url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-race
        ethnicity:
          schema:
            type: Extension
          min: 0
          max: 1
          match:
            type: pattern
            value:
              url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity
        birthsex:
          schema:
            type: Extension
          min: 0
          max: 1
          match:
            type: pattern
            value:
              url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-birthsex
        genderIdentity:
          schema:
            type: Extension
          min: 0
          max: 1
          match:
            type: pattern
            value:
              url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-genderIdentity
      discriminator:
      - type: value
        path: url
      rules: open
  identifier:
    mustSupport: true
    required:
    - system
    - value
    elements:
      system:
        mustSupport: true
      value:
        mustSupport: true
  name:
    mustSupport: true
    elements:
      family:
        mustSupport: true
      given:
        mustSupport: true
  telecom:
    required:
    - system
    - value
    elements:
      system:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/contact-point-system
          strength: required
        mustSupport: true
      value:
        mustSupport: true
      use:
        binding:
          valueSet: http://hl7.org/fhir/ValueSet/contact-point-use
          strength: required
        mustSupport: true
  gender:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/administrative-gender
      strength: required
      codesystems:
    mustSupport: true
    type: code
  birthDate:
    mustSupport: true
  address:
    mustSupport: true
    elements:
      line:
        mustSupport: true
      city:
        mustSupport: true
      state:
        binding:
          valueSet: http://hl7.org/fhir/us/core/ValueSet/us-core-usps-state
          strength: extensible
        mustSupport: true
      postalCode:
        mustSupport: true
      period:
        mustSupport: true
  communication:
    elements:
      language:
        binding:
          valueSet: http://hl7.org/fhir/us/core/ValueSet/simple-language
          strength: extensible
        mustSupport: true
derivation: constraint

With this data sample:

resourceType: Patient
active: true
gender: male
name:
  - given:
    - John
    family: Smith

The engine processes the entire resource as the data node:

resourceType: Patient
active: true
gender: male
name:
  - given:
    - John
    family: Smith

%resource & %rootResource

These variables are similar to %context and vary based on schema location:

Consider this schema:

url: "contained-invariant-profile"
base: "Patient"
elements:
  contained:
    constraints:
      cont-1:
        human: "Check context variables are set correctly"
        severity: "error"
        expression: "%context.type().name.trace('cont-1-context:') = 'Practitioner'
                     and %resource.type().name.trace('cont-1-resource') = 'Patient'
                     and %rootResource.type().name.trace('cont-1-root') = 'Patient'"
    type: "Practitioner"
    elements:
      name:
        constraints:
          cont-2:
            human: "Check context variables are set correctly"
            severity: "error"
            expression: "%context.type().name.trace('cont-2-context:') = 'HumanName'
                         and %resource.type().name.trace('cont-2-resource') = 'Practitioner'
                         and %rootResource.type().name.trace('cont-2-rootResource') = 'Patient'"
  generalPractitioner:
    constraints:
      cont-3:
        human: "Check context variables are set correctly"
        severity: "error"
        expression: "%context.type().name.trace('cont-3-context') = 'Reference'
                     and %resource.type().name.trace('cont-3-resource') = 'Patient'
                     and %rootResource.type().name.trace('cont-3-rootresource') = 'Patient'"

Testing against this data sample:

resourceType: Patient
meta:
  profile:
  - contained-invariant-profile
contained:
- resourceType: Practitioner
  name:
  - family: a
generalPractitioner:
- reference: Practitioner/1

cont-1 at elements.contained.constraints

Variables for cont-1:

%context:

- resourceType: Practitioner
  name:
    - family: a

%rootResource:

resourceType: Patient
meta:
  profile:
  - contained-invariant-profile
contained:
- resourceType: Practitioner
  name:
  - family: a
generalPractitioner:
- reference: Practitioner/1

%resource:

resourceType: Patient
meta:
  profile:
  - contained-invariant-profile
contained:
- resourceType: Practitioner
  name:
  - family: a
generalPractitioner:
- reference: Practitioner/1

cont-2 at elements.contained.name.constraints

Variables for cont-2:

%context:

- family: a

%rootResource:

resourceType: Patient
meta:
  profile:
  - contained-invariant-profile
contained:
- resourceType: Practitioner
  name:
  - family: a
generalPractitioner:
- reference: Practitioner/1

%resource:

resourceType: Practitioner
name:
 - family: a

cont-3 at elements.generalPractitioner.constraints

Variables for cont-3:

%context:

- reference: Practitioner/1

%rootResource:

resourceType: Patient
meta:
  profile:
  - contained-invariant-profile
contained:
- resourceType: Practitioner
  name:
  - family: a
generalPractitioner:
- reference: Practitioner/1

%resource:

resourceType: Patient
meta:
  profile:
  - contained-invariant-profile
contained:
- resourceType: Practitioner
  name:
  - family: a
generalPractitioner:
- reference: Practitioner/1

Human

This is a textual description of your constraint. While not mandatory, it is typically beneficial to include at least a brief explanation of your constraint.

Severity

Types of constraint severity:

  • error: Failing results in a validation error.
  • warning
  • guideline

Slice

A slice of an array is a subarray of the original array to which you can apply constraints. It is a part of Slicing.

Syntax

Match property:

  • match (Match)

Cardinality properties:

  • min (integer)
  • max (integer)

Order property:

  • order (integer)

Reslice property:

  • reslice (string)

Constrain existing slice property:

  • sliceIsConstraining (boolean)

Schema property

  • schema (Element)

Slice matching

Syntax

Type property:

  • type (string: pattern|binding|profile|type)

Resolve ref (Obtain reference target and perform checks on it?) property:

  • resolve-ref (boolean)

Pattern / Binding / Profile / Type specification property:

  • value (Object)

A slice of an array is a subarray of the original array. This subarray is selected using match expressions. Let's overview existing match types:

Pattern

This matcher type enables the specification of a pattern to be compared against each element in the source array. The comparison relies on partial equality, meaning that for an element to match, it must contain all the properties and values specified in the pattern but may also have additional properties.

To define a slice utilizing this match type, the schema would look like this:

slicing:
  slices:
    <your-slice-name>:
      match:
        type: pattern
        value:
          system: http://hl7.org/fhir/sid/us-npi

Matched data element

The following data element will be matched into the slice defined earlier:

use: official
system: http://hl7.org/fhir/sid/us-npi
value: 1346336807

Unmatched data element

The following data element won't be matched into the slice defined earlier:

use: official
system: some-custom-system
value: some-value

resolve-ref

If you are slicing a reference array and want to check your pattern against the actual reference target, not the reference data element, add the resolve-ref: true declaration.

Consider FHIR R4 lipidprofile:

url: http://hl7.org/fhir/StructureDefinition/lipidprofile|4.0.1
package-meta:
  name: hl7.fhir.r4.core
  version: 4.0.1
  path: test/fixtures/hl7.fhir.r4.core#4.0.1
excluded:
- conclusionCode
id: lipidprofile
base: http://hl7.org/fhir/StructureDefinition/DiagnosticReport|4.0.1
kind: resource
required:
- code
type: http://hl7.org/fhir/StructureDefinition/DiagnosticReport|4.0.1
datatype: DiagnosticReport
 elements:
  code:
    fixed:
      coding:
      - system: http://loinc.org
        code: 57698-3
        display: Lipid panel with direct LDL - Serum or Plasma
    type: http://hl7.org/fhir/StructureDefinition/CodeableConcept|4.0.1
    datatype: CodeableConcept
   result:
     slicing:
      discriminator:
      - type: value
        path: resolve().code
      ordered: true
      rules: closed
       slices:
         Cholesterol:
          schema:
           refers:
           - http://hl7.org/fhir/StructureDefinition/cholesterol|4.0.1
            mustSupport: true
            type: http://hl7.org/fhir/StructureDefinition/Reference|4.0.1
            datatype: Reference
          min: 1
          max: 1
          order: 0
           match:
             type: pattern
             resolve-ref: true
             value:
               code:
                 coding:
                 - system: http://loinc.org
                   code: 35200-5
                   display: Cholesterol [Moles/​volume] in Serum or Plasma
        Triglyceride:
          schema:
            refers:
            - http://hl7.org/fhir/StructureDefinition/triglyceride|4.0.1
            mustSupport: true
            type: http://hl7.org/fhir/StructureDefinition/Reference|4.0.1
            datatype: Reference
          min: 1
          max: 1
          order: 1
          match:
            type: pattern
            resolve-ref: true
            value:
              code:
                coding:
                - system: http://loinc.org
                  code: 35217-9
                  display: Triglyceride [Moles/​volume] in Serum or Plasma
        HDLCholesterol:
          schema:
            refers:
            - http://hl7.org/fhir/StructureDefinition/hdlcholesterol|4.0.1
            mustSupport: true
            type: http://hl7.org/fhir/StructureDefinition/Reference|4.0.1
            datatype: Reference
          min: 1
          max: 1
          order: 2
          match:
            type: pattern
            resolve-ref: true
            value:
              code:
                coding:
                - system: http://loinc.org
                  code: 2085-9
                  display: HDL Cholesterol
        LDLCholesterol:
          schema:
            refers:
            - http://hl7.org/fhir/StructureDefinition/ldlcholesterol|4.0.1
            mustSupport: true
            type: http://hl7.org/fhir/StructureDefinition/Reference|4.0.1
            datatype: Reference
          min: 0
          max: 1
          order: 3
          match:
            type: binding
            resolve-ref: true
            value:
              code:
                valueSet: http://hl7.org/fhir/ValueSet/ldlcholesterol-codes
                strength: required
    array: true
  conclusion:
    min: 0
    max: 1
    mustSupport: true
    type: http://hl7.org/fhir/StructureDefinition/string|4.0.1
    datatype: string
  conclusionCode:
    type: http://hl7.org/fhir/StructureDefinition/CodeableConcept|4.0.1
    datatype: CodeableConcept

Human interpretation of the slice: The first reference should point to a cholesterol resource that contains the same code as used in the value property.

Binding

This matcher enables the specification of a terminology binding that will be checked against each element in the source array. An element will be matched in the slice if it passes the terminology binding check. The array in which this slicing is defined must be one of the following types: code, Coding, or CodeableConcept.

Consider folowing US Core 5.0.1 Condition Problems and Health Concerns schema:

url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-condition-problems-health-concerns
package-meta:
  name: hl7.fhir.us.core
  version: 5.0.1
  path: "/tmp/lw-fhir-schema-repository/hl7.fhir.us.core#5.0.1"
id: us-core-condition-problems-health-concerns
base: http://hl7.org/fhir/StructureDefinition/Condition
kind: resource
required:
- category
- code
type: Condition
elements:
  abatementDateTime:
    mustSupport: true
    type: dateTime
    choiceOf: abatement
  onsetPeriod:
    mustSupport: true
    type: Period
    choiceOf: onset
  onset:
    choices:
    - onsetDateTime
    - onsetAge
    - onsetPeriod
    - onsetRange
    - onsetString
  clinicalStatus:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/condition-clinical
      strength: required
    mustSupport: true
  abatementString:
    mustSupport: true
    type: string
    choiceOf: abatement
  onsetAge:
    mustSupport: true
    type: Age
    choiceOf: onset
  abatementRange:
    mustSupport: true
    type: Range
    choiceOf: abatement
  extension:
    slicing:
      slices:
        assertedDate:
          schema:
            mustSupport: true
            type: Extension
          max: 1
          match:
            type: pattern
            value:
              url: http://hl7.org/fhir/StructureDefinition/condition-assertedDate
      discriminator:
      - type: value
        path: url
      rules: open
  onsetRange:
    mustSupport: true
    type: Range
    choiceOf: onset
  subject:
    refers:
    - http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient
    mustSupport: true
    type: Reference
  abatementAge:
    mustSupport: true
    type: Age
    choiceOf: abatement
  recordedDate:
    mustSupport: true
  onsetDateTime:
    mustSupport: true
    type: dateTime
    choiceOf: onset
  abatement:
    choices:
    - abatementDateTime
    - abatementAge
    - abatementPeriod
    - abatementRange
    - abatementString
  abatementPeriod:
    mustSupport: true
    type: Period
    choiceOf: abatement
  verificationStatus:
    binding:
      valueSet: http://hl7.org/fhir/ValueSet/condition-ver-status
      strength: required
    mustSupport: true
  category:
    mustSupport: true
    slicing:
     discriminator:
     - type: pattern
       path: "$this"
      rules: open
      slices:
        us-core:
         schema:
           binding:
             valueSet: http://hl7.org/fhir/us/core/ValueSet/us-core-problem-or-health-concern
             strength: required
           mustSupport: true
          min: 1
          match:
            type: binding
            value:
              strength: required
              valueSet: http://hl7.org/fhir/us/core/ValueSet/us-core-problem-or-health-concern
        sdoh:
          schema:
            mustSupport: true
            pattern:
              coding:
              - system: http://hl7.org/fhir/us/core/CodeSystem/us-core-tags
                code: sdoh
          min: 0
          max: 1
          match:
            type: pattern
            value:
              coding:
              - system: http://hl7.org/fhir/us/core/CodeSystem/us-core-tags
                code: sdoh
  code:
    binding:
      valueSet: http://hl7.org/fhir/us/core/ValueSet/us-core-condition-code
      strength: extensible
    mustSupport: true
  onsetString:
    mustSupport: true
    type: string
    choiceOf: onset

Human interpretation of the slice: There should be at least one CodeableConcept in category that matches the provided terminology binding.

Matched data element

The following data element will be matched into the slice defined earlier:

coding:
- system: http://terminology.hl7.org/CodeSystem/condition-category
  code: problem-list-item

Unmatched data element

The following data element won't be matched into the slice defined earlier (terminology biding violation):

coding:
- system: http://terminology.hl7.org/CodeSystem/condition-category
  code: some-random-code

Profile

This matcher type enables the specification of a reference to a profile against which data elements will be validated. If the validation returns no errors, the array element will be matched in the slice.

Consider this two custom schemas for Patient and Bundle resources:

Patient
base: http://hl7.org/fhir/StructureDefinition/Patient
id: custom-pat
url: custom-pat
type: Patient
required:
- gender
Bundle
base: http://hl7.org/fhir/StructureDefinition/Bundle
id: custom-bundle
url: custom-bundle
type: Bundle
elements:
  entry:
    slicing:
      slices:
        pat:
          min: 1
          max: 1
          match:
            type: profile
            value:
              resource: custom-pat

Human interpretation of the slice: there should be only one resource entry that fully conforms to custom-pat profile

Matched data element

The following data element (entry.0.resource) will be matched into the slice defined earlier:

meta:
  profile:
  - custom-bundle
resourceType: Bundle
type: transaction
entry:
- request:
    method: POST
    url: "/Patient"
  resource:
    resourceType: Patient
    gender: male

Unmatched data element

The following data element (entry.0.resource) won't be matched (due to missed gender property) into the slice defined earlier:

meta:
  profile:
  - custom-bundle
resourceType: Bundle
type: transaction
entry:
- request:
    method: POST
    url: "/Patient"
  resource:
    resourceType: Patient

resolve-ref

If you are slicing a reference array and want to check your profile against the actual reference target, not the reference data element, add the resolve-ref: true declaration.

url: http://hl7.org/fhir/us/davinci-alerts/StructureDefinition/transfer-notification-messageheader
package-meta:
  name: hl7.fhir.us.davinci-alerts
  version: 1.0.0
  path: test/fixtures/hl7.fhir.us.davinci-alerts#1.0.0
id: transfer-notification-messageheader
base: http://hl7.org/fhir/us/davinci-alerts/StructureDefinition/notifications-messageheader
required:
- eventCoding
- focus
type: MessageHeader
elements:
  eventCoding:
    binding:
      valueSet: http://hl7.org/fhir/us/davinci-alerts/ValueSet/notification-transfer-event
      strength: extensible
    mustSupport: true
    type: Coding
  focus:
    mustSupport: true
    slicing:
      discriminator:
      - type: profile
        path: "$this.resolve()"
      rules: open
      slices:
        discharge-notification:
          schema:
            refers:
            - http://hl7.org/fhir/us/davinci-alerts/StructureDefinition/adt-notification-encounter
            mustSupport: true
            type: Reference
          min: 1
          match:
            type: profile
            resolve-ref: true
            value: http://hl7.org/fhir/us/davinci-alerts/StructureDefinition/adt-notification-encounter
    array: true

Human interpretation of the slice: at least one reference should point to Encounter resource that fully conforms to http://hl7.org/fhir/us/davinci-alerts/StructureDefinition/adt-notification-encounter profile

Type

This matcher type enables the specification of a type against which data elements will be checked.

Consider this Davinici 0.1.0 Alerts schema:

---
url: http://hl7.org/fhir/us/davinci-alerts/StructureDefinition/notifications-bundle|1.0.0
package-meta:
  name: hl7.fhir.us.davinci-alerts
  version: 1.0.0
  path: test/fixtures/hl7.fhir.us.davinci-alerts#1.0.0
excluded:
- total
id: notifications-bundle
base: http://hl7.org/fhir/StructureDefinition/Bundle|4.0.1
required:
- id
- timestamp
type: http://hl7.org/fhir/StructureDefinition/Bundle|4.0.1
elements:
  id:
    mustSupport: true
  type:
    fixed: message
    mustSupport: true
    type: http://hl7.org/fhir/StructureDefinition/code|4.0.1
  timestamp:
    mustSupport: true
  entry:
    excluded:
    - search
    - request
    - response
    mustSupport: true
    slicing:
      discriminator:
      - type: type
        path: resource
      rules: open
      slices:
        messageheader:
          schema:
            mustSupport: true
            required:
            - resource
            elements:
              resource:
                mustSupport: true
                type: http://hl7.org/fhir/StructureDefinition/MessageHeader|4.0.1
          min: 1
          max: 1
          match:
            type: type
            value:
              resource:
                resourceType: MessageHeader
    array: true

Human interpretation of the slice: there should be only one MessageHeader resource among the bundle entries

Matched data element

The following data element (entry.0.resource) will be matched into the slice defined earlier:

resourceType: Bundle
meta:
  profile:
  - http://hl7.org/fhir/us/davinci-alerts/StructureDefinition/notifications-bundle
type: message
entry:
- resource:
    resourceType: MessageHeader
    eventCoding:
      code: code
    source:
      endpoint: google.com

Unmatched data element

The following data element (entry.0.resource) won't be matched (due to wrong resource type) into the slice defined earlier:

resourceType: Bundle
meta:
  profile:
  - http://hl7.org/fhir/us/davinci-alerts/StructureDefinition/notifications-bundle
type: message
entry:
- resource:
    resourceType: Patient

resolve-ref

If you are slicing a reference array and want to check your reference type add the resolve-ref: true declaration.

Consider this IHE Interactive Multimedia Report (IMR) DiagnosticReport schema

url: https://profiles.ihe.net/RAD/imr/StructureDefinition/imr-diagnosticreport
package-meta:
  name: ihe.rad.imr
  version: 0.1.0
  path: "/tmp/lw-fhir-schema-repository/ihe.rad.imr#0.1.0"
id: imr-diagnosticreport
base: http://hl7.org/fhir/StructureDefinition/DiagnosticReport
kind: resource
required:
- basedOn
- category
- subject
- effective
- effectiveDateTime
- issued
- performer
- resultsInterpreter
- result
- imagingStudy
- presentedForm
type: DiagnosticReport
elements:
  effectiveDateTime:
    mustSupport: true
    type: dateTime
  resultsInterpreter:
    refers:
    - http://hl7.org/fhir/StructureDefinition/Practitioner
    - http://hl7.org/fhir/StructureDefinition/PractitionerRole
    type: Reference
  presentedForm:
    constraints:
      IMRAttachmentInvariant:
        human: Either data or url SHALL be present
        severity: error
        expression: data.exists() or url.exists()
    mustSupport: true
    required:
    - contentType
    - size
    - hash
    slicing:
      discriminator:
      - type: pattern
        path: contentType
      description: Slice based on the presentedForm content type
      ordered: false
      rules: open
      slices:
        html:
          schema:
            elements:
              contentType:
                pattern: text/html
          min: 1
          max: 2147483647
          match:
            type: pattern
            value:
              contentType: text/html
        pdf:
          schema:
            elements:
              contentType:
                pattern: applicatoin/pdf
          min: 0
          max: 2147483647
          match:
            type: pattern
            value:
              contentType: applicatoin/pdf
    elements:
      contentType:
        mustSupport: true
      size:
        mustSupport: true
      hash:
        mustSupport: true
  basedOn:
    mustSupport: true
    slicing:
      discriminator:
      - type: type
        path: resolve()
      description: Slice based on the basedOn reference type
      ordered: false
      rules: open
      slices:
        serviceRequest:
          schema:
            refers:
            - https://profiles.ihe.net/RAD/imr/StructureDefinition/imr-servicerequest
            type: Reference
          min: 1
          max: 2147483647
          match:
            resolve-ref: true
            type: type
            value: ServiceRequest
  imagingStudy:
    refers:
    - https://profiles.ihe.net/RAD/imr/StructureDefinition/imr-imagingstudy
    mustSupport: true
    type: Reference
  extension:
    slicing:
      discriminator:
      - type: value
        path: url
      ordered: false
      rules: open
      slices:
        comparisonStudy:
          schema:
            mustSupport: true
            type: Extension
          min: 0
          max: 2147483647
          match:
            type: pattern
            value:
              url: https://profiles.ihe.net/RAD/imr/StructureDefinition/comparisonStudy
        indication:
          schema:
            mustSupport: true
            type: Extension
          min: 0
          max: 2147483647
          match:
            type: pattern
            value:
              url: https://profiles.ihe.net/RAD/imr/StructureDefinition/indication
  status:
    binding:
      valueSet: https://profiles.ihe.net/RAD/imr/ValueSet/imr-diagnosticreport-status-vs
      strength: required
      codesystems:
      - http://hl7.org/fhir/diagnostic-report-status
  subject:
    refers:
    - http://hl7.org/fhir/StructureDefinition/Patient
    type: Reference
  result:
    refers:
    - https://profiles.ihe.net/RAD/imr/StructureDefinition/imr-observation
    mustSupport: true
    type: Reference
  performer:
    slicing:
      discriminator:
      - type: type
        path: resolve()
      description: Slice based on the performer reference type
      ordered: false
      rules: open
      slices:
        organization:
          schema:
            refers:
            - http://hl7.org/fhir/StructureDefinition/Organization
            type: Reference
          min: 1
          max: 1
          match:
            resolve-ref: true
            type: type
            value: Organization
derivation: constraint

Matched data element

The following data element (performer.0) will be matched into the slice defined earlier:

meta:
  profile:
  - https://profiles.ihe.net/RAD/IMR/StructureDefinition/imr-diagnosticreport
resourceType: DiagnosticReport
performer:
- reference: Organization/1

Unmatched data element

The following data element (performer.0) won't be matched (due to wrong reference type) into the slice defined earlier:

meta:
  profile:
  - https://profiles.ihe.net/RAD/IMR/StructureDefinition/imr-diagnosticreport
resourceType: DiagnosticReport
performer:
- reference: Practitioner/1

Human interpretation of the slice: there should be only one performer reference of type Organization

Cardinality

You can constrain the number of elements your slice will match by providing min and max properties. Omit the max property to match an unlimited number of elements. To make a slice required, provide a min value of 1 or greater.

Consider following US Core 5.0.1 race extension schema

url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-race
package-meta:
  name: hl7.fhir.us.core
  version: 5.0.1
  path: "/tmp/lw-fhir-schema-repository/hl7.fhir.us.core#5.0.1"
excluded:
- value
id: us-core-race
base: http://hl7.org/fhir/StructureDefinition/Extension
kind: complex-type
required:
- url
type: Extension
elements:
  extension:
    slicing:
      slices:
        ombCategory:
          schema:
            mustSupport: true
            required:
            - url
            - value
            type: Extension
            elements:
              url:
                scalar: true
                fixed: ombCategory
                type: uri
              valueCoding:
                binding:
                  valueSet: http://hl7.org/fhir/us/core/ValueSet/omb-race-category
                  strength: required
                scalar: true
                required-element: true
                type: Coding
                choiceOf: value
              value:
                choices:
                - valueCoding
                scalar: true
          min: 0
          max: 5
          match:
            type: pattern
            value:
              url: ombCategory
        detailed:
          schema:
            required:
            - url
            - value
            type: Extension
            elements:
              url:
                scalar: true
                fixed: detailed
                type: uri
              valueCoding:
                binding:
                  valueSet: http://hl7.org/fhir/us/core/ValueSet/detailed-race
                  strength: required
                scalar: true
                required-element: true
                type: Coding
                choiceOf: value
              value:
                choices:
                - valueCoding
                scalar: true
          min: 0
          max: 2147483647
          match:
            type: pattern
            value:
              url: detailed
        text:
          schema:
            scalar: true
            mustSupport: true
            required:
            - url
            - value
            type: Extension
            elements:
              url:
                scalar: true
                fixed: text
                type: uri
              valueString:
                scalar: true
                required-element: true
                type: string
                choiceOf: value
              value:
                choices:
                - valueString
                scalar: true
          min: 1
          max: 1
          match:
            type: pattern
            value:
              url: text
      discriminator:
      - type: value
        path: url
      rules: open
  url:
    scalar: true
    fixed: http://hl7.org/fhir/us/core/StructureDefinition/us-core-race
derivation: constraint

Valid case

The following data elements will be matched into the slices defined earlier:

extension:
- url: ombCategory
  valueCoding:
    system: urn:oid:2.16.840.1.113883.6.238
    code: 2028-9
    display: Asian
- url: text
  valueString: Asian
url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-race

Invalid case

Due to the absence of text, the text slice won't be matched, resulting in a validation error, since the text slice is required.

extension:
- url: ombCategory
  valueCoding:
    system: urn:oid:2.16.840.1.113883.6.238
    code: 2028-9
    display: Asian
url: http://hl7.org/fhir/us/core/StructureDefinition/us-core-race

Order

Defines the slice order in the case of ordered slicing. Please refer to ordered slicing specification page.

Reslice

It's sometimes necessary to slice data that has already been sliced in the base profile - that is, create new slices within the existing slices. This is called Re-slicing. Using reslice property you can refer to an existing slice and start re-slicing definition.

Consider this two custom schemas:

Schema foo
base: http://hl7.org/fhir/StructureDefinition/Patient
type: Patient
elements:
  address:
    type: Address
    array: true
    slicing:
      rules: closed
      slices:
        homeaddress:
          min: 1
          match:
            type: pattern
            value:
              use: home

Human interpretation of the slice: there should be at least one address with use: home

Schema bar
base: foo
type: Patient
elements:
  address:
    type: Address
    array: true
    slicing:
      slices:
        homeaddress/a:
          reslice: homeaddress
          max: 2
          match:
            type: pattern
            value:
              text: foo

Human interpretation of the slice: Within elements matched to the homeaddress slice, there should be a maximum of 2 elements with text: foo.

Valid case

The following addresses will be matched into the slices defined earlier:

resourceType: Patient
meta:
  profile:
  - bar
address:
- use: home
  text: foo
- use: home
  text: foo

Invalid case

The following addresses won't be matched into the homeaddress/a re-slice defined earlier due to max limit (2) exceed:

resourceType: Patient
meta:
  profile:
  - bar
address:
- use: home
  text: foo
- use: home
  text: foo
- use: home
  text: foo

Constraining existing slice

You can further constrain slice defined earlier in parent schemas by using same slice name and setting sliceIsConstraining property to true. Usually it's a good way to forbid an optional slice.

Consider following custom schemas:

Schema foo
base: http://hl7.org/fhir/StructureDefinition/Patient
type: Patient
elements:
  address:
    type: Address
    array: true
    slicing:
      slices:
        homeaddress:
          match:
            type: pattern
            value:
              use: home
Schema bar
base: foo
type: Patient
elements:
  address:
    type: Address
    array: true
    slicing:
      slices:
        homeaddress:
          sliceIsConstraining: true
          max: 0

Valid case

The following addresses won't be matched in any of slices defined earlier.

resourceType: Patient
meta:
  profile:
  - bar
address:
- use: office
  text: foo

Invalid case

The following addresses will be matched into the homeaddress slice, which violates our additional constraint in the profile bar.

resourceType: Patient
meta:
  profile:
  - bar
address:
- use: home
  text: foo

@default slice

Reserved slice ID, you can mention this slice only if you have closed slicing; all unmatched data elements will be checked against this slice.

Consider following custom schema:

base: http://hl7.org/fhir/StructureDefinition/Patient
type: Patient
elements:
  address:
    slicing:
      rules: closed
      ordered: true
      slices:
        homeaddress:
          min: 1
          match:
            type: pattern
            value:
              use: home
          order: 0
        "@default":
          schema:
            required:
            - type
            elements:
              use:
                fixed: billing
          order: 1

Human description of the slice: there shoud be at least one address with use: home, also it should preced addresses with use: billing

Valid case

The following addresses will be matched into the slices defined earlier.

resourceType: Patient
meta:
  profile:
  - bar
address:
- use: home
- use: billing

Invalid case

The following addresses won't be matched into the slices defined earlier due to incorrect order.

resourceType: Patient
meta:
  profile:
  - bar
address:
- use: billing
- use: home

Schema

After an element is matched by the match property, you can define additional constraints via the schema property. This property is essentially an Element, and the matched data element will be validated against the provided schema as usual. If the validator produces errors during the validation of this element, it will count as an unmatched slice element.

Consider following custom schema:

base: Patient
url: custom-pat
elements:
  name:
    slicing:
      slices:
        off-name:
          schema:
            constraints:
              off-nam-constr-1:
                expression: given.exists() or family.exists()
                severity: error
          match:
            type: pattern
            min: 1
            value:
              use: official

Human description of the slice: there should be at least one name with use: official, this name must contain given or family.

Valid case

The following name will be matched into slice defined earlier.

resourceType: Patient
name:
  - use: official
    given:
      - John

Invalid cases

No official name.

resourceType: Patient
name:
  - use: nickname
    given:
      - test

No given or family.

resourceType: Patient
name:
  - use: official
    text: test

Slicing

Slicing is an Element property that dividing an arrays to sub-arrays with specific constraints on each sub-array.

Syntax

Slices in slicing

  • slices (object)

Ordered flag

  • ordered (boolean)

Slicing rules type

  • rules (string)

Slices

There can be multiple slices in slicing. The value of the slices property is an object, where keys are slice names, and values are slice elements.

That is, slices property looks like:

slices:
  slice-name-1: <slice>
  slice-name-2: <slice>

Note: slice names shall be unique per schema.

Slicing order

Property ordered forces special order for slices.

If the ordered property is true, each slice requires an order property, which is the number in the order of the slices. Items in the list must be ordered to match slices in the specified order.

Example

Schema

url:  http://example.com/Patient/patient
base: http://hl7.org/fhir/StructureDefinition/Patient
type: Patient
name: Patient-slicing
elements:
  address:
    slicing:
      ordered: true
      slices:
        first:
          order: 0
          match:
            type: pattern
            value:
              use: home
        other:
          order: 1
          match:
            type: pattern
            value:
              use: work

Valid resources

meta:
  profile: 
    - http://example.com/Patient/patient|1.0.0
resourceType: Patient
address:
  - use: home
    text: Bos en Lommerplein 280
  - use: work
    text: 534 Erewhon St PeasantVille, Rainbow, Vic  3999
meta:
  profile: 
    - http://example.com/Patient/patient|1.0.0
resourceType: Patient
address:
  - use: home
    text: Bos en Lommerplein 280
  - use: home
    text: Bos en Lommerplein 285
  - use: work
    text: 534 Erewhon St PeasantVille, Rainbow, Vic  3999

Invalid resources

meta:
  profile: 
    - http://example.com/Patient/patient|1.0.0
resourceType: Patient
address:
  - use: work
    text: 534 Erewhon St PeasantVille, Rainbow, Vic  3999
  - use: home
    text: Bos en Lommerplein 280
meta:
  profile: 
    - http://example.com/Patient/patient|1.0.0
resourceType: Patient
address:
  - use: home
    text: Bos en Lommerplein 280
  - use: work
    text: 534 Erewhon St PeasantVille, Rainbow, Vic  3999
  - use: home
    text: Bos en Lommerplein 285

Slicing rules

The rules property specifies validation rules:

  • open: no additional restrictions will be imposed;
  • closed: all items must match at least one slice;
  • openAtEnd: all items that do not correspond to any slice must be at the end of the list. This option requires the ordered property to be true.

The default is open.

Example

Schema with closed rules

url:  http://example.com/Patient/patient
base: http://hl7.org/fhir/StructureDefinition/Patient
type: Patient
name: Patient-slicing
elements:
  address:
    slicing:
      rules: closed
      slices:
        home:
          match:
            type: pattern
            value:
              use: home

Invalid resource

meta:
  profile: 
    - http://example.com/Patient/patient|1.0.0
resourceType: Patient
address:
  - use: home
    text: Bos en Lommerplein 280
  - use: work
    text: 534 Erewhon St PeasantVille, Rainbow, Vic  3999

Valid resource

meta:
  profile: 
    - http://example.com/Patient/patient|1.0.0
resourceType: Patient
address:
  - use: home
    text: Bos en Lommerplein 280
  - use: home
    text: Bos en Lommerplein 285

Schema with openAtEnd rules

url:  http://example.com/Patient/patient
base: http://hl7.org/fhir/StructureDefinition/Patient
type: Patient
name: Patient-slicing
elements:
  address:
    slicing:
      rules: openAtEnd
      ordered: true
      slices:
        home:
          order: 0
          match:
            type: pattern
            value:
              use: home
        work:
          order: 1
          match:
            type: pattern
            value:
              use: work

Invalid resource

meta:
  profile: 
    - http://example.com/Patient/patient|1.0.0
resourceType: Patient
address:
  - use: temp
    text: 524 Erewhon St PeasantVille, Rainbow, Vic  3992
  - use: home
    text: Bos en Lommerplein 280
  - use: work
    text: 534 Erewhon St PeasantVille, Rainbow, Vic  3999

Valid resource

meta:
  profile: 
    - http://example.com/Patient/patient|1.0.0
resourceType: Patient
address:
  - use: home
    text: Bos en Lommerplein 280
  - use: work
    text: 534 Erewhon St PeasantVille, Rainbow, Vic  3999
  - use: temp
    text: 524 Erewhon St PeasantVille, Rainbow, Vic  3992

Extensions

Extensions make schemas incompatible with FHIR!

Use only if there is no other way to model your data.

FHIR-Schema defines optional extensions. These extensions allow to model data not representable in FHIR otherwise. However when using these extensions it is not possible to convert FHIR-Schema into equivalent StructureDefinition.

Enable Fhir-schema extensions

To enable FHIR-Schema extensions, the following key must be present at the top level of a FHIR-Schema definition:

ALLOW_FHIR_SCHEMA_FHIR_INCOMPATIBLE_EXTENSIONS: true

Any extensions are allowed ONLY for schemas with

derivation: specialization

If any extensions found in the schema while the key described above is not present, the schema is rejected as invalid.

Available extensions

any

Any element (including the top-level one) can contain the

any: true

property. If this property is present, the contents of the corresponding subtree of a resource is not validated.

Usage example

ALLOW_FHIR_SCHEMA_FHIR_INCOMPATIBLE_EXTENSIONS: true
url: schema-1
elements:
  knownElement:
    any: true

Limitations

The any property exlusive with any other properties:

  • If there are multiple schemas for an element, where at least one specifies the any property, it will be rejected as invalid.
  • If there are multiple schemas for an element, where at least one specifies any other property, it will be rejected as invalid.

For example, this is prohibited:

ALLOW_FHIR_SCHEMA_FHIR_INCOMPATIBLE_EXTENSIONS: true
url: schema-1
elements:
  knownElement:
    any: true
---
ALLOW_FHIR_SCHEMA_FHIR_INCOMPATIBLE_EXTENSIONS: true
url: schema-2
base: schema-1
elements:
  knownElement:
    type: string

additionalProperties

Any element (including the top-level one) can contain the

additionalProperties:
  # <schema for additional properties>

property. Any key which does not correspond to any key defined in the elements property is validated using the schema supplied under the additionalProperties property.

Usage example

The following example means that any property except knownElement and _knownElement is allowed and valid if it is a string value.

Schema:

ALLOW_FHIR_SCHEMA_FHIR_INCOMPATIBLE_EXTENSIONS: true
url: schema-1
elements:
  knownElement:
    type: integer
additionalProperties:
  type: string

Valid resource:

knownElement: 1
_knownElement:
  id: test
unknownElement: stringValue
_unknownElement: test2
______: test3

Invalid resources:

knownElement: 1
unknownElement: 2
---
knownElement: 1
_knownElement: test

Limitations

FHIR reserves the underscore (_) characters in property names. FHIR JSON representation separates any element in two parts:

  • propertyName
  • _propertyName

Property resolution behavior:

  • If the property does not start with underscore and is defined in elements, it is interpreted as a normal part of the corresponding element.
  • If the property starts with a single underscore, and the corresponding property name without underscore is defined in elements, it is interpreted as an underscored part of the corresponding element.
  • Otherwise, it is interpreted as a normal part of an element specified under the additionalProperties property (regardless of underscores).

Extensions reserved for future use

The following properties are reserved for future use:

  • properties
  • additionalElements