FHIRPath
FHIRPath is a language, similar to XPath, that allows you to navigate a FHIR® resource to evaluate and extract data from its fields using a straightforward syntax that includes paths, functions, and operations. For example, you could evaluate whether the given name of a Patient contained a value: Patient.name.given.empty(). Or you could extract the value of the Patient resource’s telecom field, but only if offical is the value of its use field: Patient.telecom.where(use = 'official').
In FHIRPath, expressions are collection-based. Each function works on one input collection and each binary operator operates on two input collections, and the values returned by the expression are gathered into an output collection. Some functions and operations place constraints on the size of their input collections.
For complete details about FHIRPath including how to build an expression, see the HL7 FHIRPath specificationOpens in a new tab. InterSystems supports a subset of the functions and operations that are defined in the specification.
Workflow
With InterSystems technology, the process of using FHIRPath to evaluate and extract data from a resource is straightforward:
The following sections provide details about each step in the workflow.
Instantiate HS.FHIRPath.API
The process of using FHIRPath to evaluate and extract data from a resource begins with calling HS.FHIRPath.API.getInstance()Opens in a new tab. When you call this method, you must specify the FHIR package that corresponds to a version of FHIR. For example, if the resources you are evaluating conform to FHIR R4, the corresponding package ID is currently hl7.fhir.r4.core@4.0.1. In this case, instantiating HS.FHIRPath.APIOpens in a new tab would look like:
set fhirPathAPI = ##class(HS.FHIRPath.API).getInstance($lb("hl7.fhir.r4.core@4.0.1"))
You can obtain the IDs of the currently loaded packages using the Management Portal or ObjectScript:
-
Management Portal — Navigate to Home > Health > MyFHIRNamespace > FHIR Configuration, and select the Package Configuration card. The package ID is obtained by appending the @ symbol and version number to the name of the package. For example, the ID of the following package is hl7.fhir.r4.core@4.0.1:
-
ObjectScript — To list package IDs programmatically, see Listing Available Packages.
The HS.FHIRPath.APIOpens in a new tab object includes the methods used to parse FHIRPath expressions and evaluate resources. This object is also included as a property on the HS.FHIRMeta.APIOpens in a new tab object under the FHIRPathAPI property.
Parse the FHIRPath Expression
Once you have instantiated the HS.FHIRPath.APIOpens in a new tab object, you are ready to parse the FHIRPath expression. The method that parses the expression, HS.FHIRPath.API.parse()Opens in a new tab, returns a tree structure that is used by the methods that evaluate a resource. For example, assuming you have an object named fhirPathAPI instantiated as shown in the previous section:
set tree = fhirPathAPI.parse("name.given.empty()")
Evaluate the Resource
Once you have parsed the FHIRPath expression, you can use its tree structure to evaluate or extract data from a resource. Two evaluation methods are available:
In both cases, the resource being evaluated is passed into the method as a dynamic object. The tree that was returned by the parse() method is also passed as an argument. For example:
set tree = fhirPathAPI.parse("name.given.empty()")
// myResource is a dynamic object
do fhirPathAPI.evaluate(myResource, tree, .OUTPUT)
set DynArray = fhirPathAPI.evaluateToJson(myResource, tree)
An additional method, HS.FHIRPath.API.evaluateArray()Opens in a new tab, can be used to parse the multidimensional array returned by the evalaute() method.
Work with the Results
While working with results in a dynamic array that is produced by evaluateToJson() has its benefits, the multidimensional array produced by evaluate() contains additional information that is not otherwise available. The following provides a guide to the data in the multidimensional array, assuming that your response to evaluate() was returned in a variable named OUTPUT.
Node |
Description |
OUTPUT |
Number of nodes in the array that contain values. |
OUTPUT(n) |
Value of the nth element of the array. |
OUTPUT(n,"t") |
Data type of the nth element in the array, including identifying FHIR data types. |
You can further parse the returned multidimensional array using the evaluateArray() method.
By contrast. when using the evaluateToJson() method to produce a dynamic array, you can determine whether the data type is a string, boolean, number, or object from looking at the values in the array, but you cannot determine the FHIR data type.
Workflow Example: evaluate() Method
This example includes the resource being evaluated, the ObjectScript needed to evaluate the resource, and a look at the multidimensional array produced by the evaluation.
Sample Resource
set myResource = {
"resourceType":"Patient",
"telecom": [
{
"system": "phone",
"value": "(03) 5555 6473",
"use": "official"
},
{
"system": "phone",
"value": "(03) 5555 6473",
"use": "home"
},
{
"system": "email",
"value": "myName@email.com",
"use": "official"
}
]
}
Extracting Data from the Resource
set fhirVersion = $lb("hl7.fhir.r4.core@4.0.1")
set fhirPathAPI = ##class(HS.FHIRPath.API).getInstance(fhirVersion)
set tree = fhirPathAPI.parse("telecom.where(use = 'official')")
do fhirPathAPI.evaluate(myResource, tree, .OUTPUT)
Viewing the Multidimensional Array
If you used the zw OUTPUT command in the InterSystems Terminal to view the multidimensional array returned by evaluate(), the result would be:
OUTPUT=2
OUTPUT(1)={"system":"phone","value":"(03) 5555 6473","use":"official"}
OUTPUT(1,"t")="ContactPoint"
OUTPUT(2)={"system":"email","value":"myName@email.com","use":"official"}
OUTPUT(2,"t")="ContactPoint"
Notice that the values are identified as a ContactPoint FHIR data type.
Workflow Example: evaluateArray() Method
This example takes the multidimensional array produced by the evaluation in the evaluate() example above as input and demonstrates the ObjectScript needed to evaluate the resulting array, and looks at the multidimensional array produced by the evaluation.
Extracting Data from the Output Array
Merge INPUT = OUTPUT
Kill OUTPUT
Set tree = fhirPathAPI.parse("ContactPoint.value")
do fhirPathAPI.evaluateArray(.INPUT, tree, .OUTPUT)
Viewing the Multidimensional Array
If you used the zw OUTPUT command in the InterSystems Terminal to view the multidimensional array returned by evaluateArray(), the result would be:
OUTPUT=2
OUTPUT(1)="(03) 5555 6473"
OUTPUT(1,"t")="string"
OUTPUT(2)=”myName@email.com"
OUTPUT(2,"t")="string"
Notice that the values are identified by their ObjectScript data type (string, boolean, number, or object).
Workflow Example: evaluateToJson() Method
This example includes the resource being evaluated, the ObjectScript needed to evaluate the resource, and a look at the dynamic array produced by the evaluation.
Sample Resource
set myResource = {
"resourceType":"Patient",
"name": [
{
"family": "Cooper",
"given": [
"James",
"Fenimore"
]
}]
}
Evaluating the Resource
set fhirVersion = $lb("hl7.fhir.r4.core@4.0.1")
set fhirPathAPI = ##class(HS.FHIRPath.API).getInstance(fhirVersion)
set tree = fhirPathAPI.parse("name.given.empty()")
set dynArray = fhirPathAPI.evaluateToJson(myResource, tree)
Viewing the Dynamic Array
If you used the zw dynArray command in the InterSystems Terminal to view the dynamic array, the result would be:
dynArray=[false]
Functions
The FHIRPath specification defines a wide range of functions that can be used in an expression. InterSystems supports a subset of those functions.
Supported FHIRPath Functions
Operations
The FHIRPath specification defines a wide range of operations that can be used in an expression. InterSystems supports a subset of those operations.
Supported FHIRPath Operations
Implementation Notes for as
According to the FHIRPath specification, the left operand of the asOpens in a new tab operation must be a collection with a single item. However, the InterSystems implementation of FHIRPath allows this collection to have multiple values. For example, suppose you have an Observation with multiple extensions that reference a Patient. With the InterSystems implementation of FHIRPath, the following expression would still be valid: extension.value as Reference.
Improving Performance
InterSystems provides an in-memory cache that can store parsed FHIRPath expressions, improving performance when you have a set of expressions that are repeated frequently. Once the cache is enabled, tree structures produced by the parse() method are stored until the cache is cleared.
To enable the in-memory cache, call:
do fhirPathAPI.enableCache(1)
To disable the cache, call:
do fhirPathAPI.enableCache(0)