This page is part of the FHIR Specification (v3.3.0: R4 Ballot 2). The current version which supercedes this version is 5.0.0. For a full list of available versions, see the Directory of published versions . Page versions: R5 R4B R4
FHIR Infrastructure Work Group | Maturity Level: 4 | Ballot Status: Normative |
FHIRPath is a separate specification published at http://hl7.org/fhirpath in order to support wider re-use across multiple specifications.
FHIRPath is a path-based navigation and extraction language, somewhat like XPath. Operations are expressed in terms of the logical content of hierarchical data models, and support traversal, selection and filtering of data.
FHIRPath is used in several places in the FHIR and related specifications:
In addition, FHIRPath is used in pre-fetch templates in Smart on FHIR’s cds-hooks .
FHIRPath uses a tree model that abstracts away the actual underlying datamodel of the data being queried. For FHIR, this means that the contents of the resources and data types as described in the Logical views (or the UML diagrams) are used as the model, rather than the JSON and XML formats, so specific xml or json features are not visible to the FHIRPath language (such as comments and the split representation of primitives).
More specifically:
contained
element node does not have the name of the Resource as its first and only child (instead it directly contains the contained resource’s children)
For choice elements, where elements can be one of multiple types, e.g. Patient.deceased[x]
.
In actual instances these will be present as either Patient.deceasedBoolean
or Patient.deceasedDateTime
.
In FHIRPath, choice elements are labeled according to the name without the '[x]' suffix, and children can be explicitly treated
as a specific type using the as
operation:
(Observation.value as Quantity).unit
The evaluation engine will automatically convert the value of FHIR types representing primitives to FHIRPath types when they are used in expressions according to the following mapping:
FHIR primitive type | FHIRPath type |
---|---|
boolean | Boolean |
string, uri, code, oid, id, uuid, sid, markdown, base64Binary | String |
integer, unsignedInt, positiveInt | Integer |
decimal | Decimal |
date, dateTime, instant | DateTime |
time | Time |
Note that FHIR primitives may contain extensions, so that the following expressions are not mutually exclusive:
Patient.name.given = 'Ewout' // value of Patient.name.given as a string Patient.name.given.extension.first().value = true // extension of the primitive value
FHIR adds (compatible) functionality to the common set of functions:
extension(url : string) : collection
Will filter the input collection for items named "extension" with the given url. This is a syntactical shortcut for .extension.where(url = string)
, but is simpler to write. Will return an empty collection if the input collection is empty or the url is empty.
hasValue() : Boolean
Returns true if the input collection contains a single value which is a FHIR primitive, and it has a primitive value (e.g. as opposed to not having a value and just having extensions).
Note to implementers: The FHIR conceptual model talks about "primitives" as subclasses of the type Element that also have id and extensions. What this actually means is that a FHIR primitive is not a primitive in an implementation language. The introduction (section 2 above) describes the navigation tree as if the the FHIR model applies - primitives are both primitives and elements with children.
In FHIRPath, this means that FHIR primitives have a
value
child, but they are automatically cast to FHIRPath primitives when comparisons are made, and that the primitive value will be included in the set returned bychildren()
ordescendents()
.
trace(name : string) : collection
When FHIRPath statements are used in an invariant, the log contents should be added to the error message constructed when the invariant is violated. For example:
"SHALL have a local reference if the resource is provided inline (url: height; ids: length,weight)" from "reference.startsWith('#').not() or ($context.reference.substring(1).trace('url') in $resource.contained.id.trace('ids'))"
resolve() : collection
For each item in the collection, if it is a string that is a URI or (canonical or URL), locate the target of the reference, and add it to the resulting collection. If the item does not resolve to a resource, the item is ignored and nothing is added to the output collection.
The items in the collection may also represent a Reference, in which case the Reference.reference
is resolved.
ofType(type : identifier) : collection
In FHIR, only concrete core types are allowed as an argument. All primitives are considered to be independent types (so markdown
is not a subclass of string
). Profiled types are not allowed, so to select SimpleQuantity
one would pass Quantity
as an argument.
elementDefinition() : collection
Returns the FHIR element definition information for each element in the input collection.
slice(structure : string, name : string) : collection
Returns the given slice as defined in the given structure definition. The structure argument is a uri that resolves to the structure definition, and the name must be the name of a slice within that structure definition. If the structure cannot be resolved, or the name of the slice within the resolved structure is not present, an error is thrown.
For every element in the input collection, if the resolved slice is present on the element, it will be returned. If the slice does not match any element in the input collection, or if the input collection is empty, the result is an empty collection ({ }
).
checkModifiers([{modifier : string}]) : collection
For each element in the input collection, verifies that there are no modifying extensions defined other than the ones given by the modifier
argument. If the check passes, the input collection is returned. Otherwise, an error is thrown.
conformsTo(structure : string) : Boolean
Returns true
if the single input element conforms to the profile specified by the structure
argument, and false otherwise. If the structure cannot be resolved to a valid profile, an error is thrown. If the input contains more than one element, an error is thrown. If the input is empty, the result is empty.
memberOf(valueset : string) : Boolean
When invoked on a code-valued element, returns true if the code is a member of the given valueset. When invoked on a concept-valued element, returns true if any code in the concept is a member of the given valueset. When invoked on a string, returns true if the string is equal to a code in the valueset, so long as the valueset only contains one codesystem. If the valueset in this case contains more than one codesystem, an error is thrown.
If the valueset cannot be resolved as a uri to a value set, an error is thrown.
Note that implementations are encouraged to make use of a terminology service to provide this functionality.
For example:
Observation.component.where(code.memberOf('http://hl7.org/fhir/ValueSet/observation-vitalsignresult'))
This expression returns components that have a code that is a member of the observation-vitalsignresult valueset.
subsumes(code : Coding | CodeableConcept) : Boolean
When invoked on a Coding-valued element and the given code is Coding-valued, returns true if the source code is equivalent to the given code, or if the source code subsumes the given code (i.e. the source code is an ancestor of the given code in a subsumption hierarchy), and false otherwise.
If the Codings are from different code systems, the relationships between the code systems must be well-defined or a run-time error is thrown.
When the source or given elements are CodeableConcepts, returns true if any Coding in the source or given elements is equivalent to or subsumes the given code.
Note that implementations are encouraged to make use of a terminology service to provide this functionality.
subsumedBy(code: Coding | CodeableConcept) : Boolean
When invoked on a Coding-valued element and the given code is Coding-valued, returns true if the source code is equivalent to the given code, or if the source code is subsumed by the given code (i.e. the given code is an ancestor of the source code in a subsumption hierarchy), and false otherwise.
If the Codings are from different code systems, the relationships between the code systems must be well-defined or a run-time error is thrown.
When the source or given elements are CodeableConcepts, returns true if any Coding in the source or given elements is equivalent to or subsumed by the given code.
Note that implementations are encouraged to make use of a terminology service to provide this functionality.
~ (Equivalence)
Equivalence works in exactly the same manner, but with the addition that for complex types, equality requires all child properties to be equal, except for "id" elements.
In addition, for Coding values, equivalence is defined based on the code and system elements only. The version, display, and userSelected elements are ignored for the purposes of determining Coding equivalence.
For CodeableConcept values, equivalence is defined as a non-empty intersection of Coding elements, using equivalence. In other words, two CodeableConcepts are considered equivalent if any Coding in one is equivalent to any Coding in the other.
The FHIR specification adds support for additional environment variables:
The following environmental values are set for all contexts:
%sct // (string) url for snomed ct %loinc // (string) url for loinc %"vs-[name]" // (string) full url for the provided HL7 value set with id [name] %"ext-[name]" // (string) full url for the provided HL7 extension with id [name] %resource // The original resource current context is part of. When evaluating a datatype, this would be the resource the element is part of. Do not go past a root resource into a bundle, if it is contained in a bundle. // Note that the names of the `vs-` and `ext-` constants are quoted (just like paths) to allow "-" in the name.
For example:
Observation.component.where(code.memberOf(%"vs-observation-vitalsignresult"))
This expression returns components that have a code that is a member of the observation-vitalsignresult valueset.
Note: Implementation Guides are allowed to define their own externals, and implementers should provide some appropriate configuration framework to allow these constants to be provided to the evaluation engine at run-time. E.g.:
%"us-zip" = '[0-9]{5}(-[0-9]{4}){0,1}'
Authors of Implementation Guides should be aware that adding specific environment variables restricts the use of the FHIRPath to their particular context.
Note that these tokens are not restricted to simple types, and they may have fixed values that are not known before evaluation at run-time, though there is no way to define these kind of values in implementation guides.
This page documents a restricted subset of the FHIRPath language that is used in a few contexts in this specification. When the restricted FHIRPath language subset is in use, the following rules apply:
These rules exist to keep processing the path simple to support use of the path by processors that are not backed by a full FHIRPath implementation.
The following locations use this restricted FHIRPath language: