This document defines the RDF representation of FHIR Resources.

Notation

This document uses an abstact syntax consisting of productions defining data structures and labeled members of those data structures. Each member had either a type or a union (choice) of types. Each type is either a reference to another production, RDF type, or SPARQL literal term (e.g. numeric), or the template type of List or Set, which signify logical lists or logical sets of a type. Sets are unordered and duplicates members have no significance; the set (1, 1, 2, 3, 5) is the same as the set (5, 1, 3, 2).

For example, the text:

StructureDefinition ::= name:string, type:FHIRResource|PrimativeType, declarations:List[PropertyDeclaration]

signifies that a StructureDefinition has three components called name, type and declarations. The name is a string, the type is either a FHIRResource or a PrimativeType, and the declarations are a list of PropertyDeclarations. FHIRResource, PrimativeType and PropertyDeclaration are productions within this document.

The following HTML tags and CSS classes are used to highlight the roles of text in this document:

Introduction

HL7 Fast Healthcare Interoperability Resources (FHIR) is an emerging standard for the exchange of electronic healthcare information [[FHIR]]. FHIR defines a collection of "resources" that "can easily be assembled into working systems that solve real world clinical and administrative problems at a fraction of the price of existing alternatives." This assembly process typically requires "profiling" -- the adaptation of the FHIR base resources for use in clinical data exchange. The core FHIR resources are described by FHIR-specific schema structures using the StructureDefinition resource. [[FHIRStructureDefintion]] FHIR is represented in XML, JSON and RDF.

FHIR Resources

The FHIR specification [[FHIR]] defines resources, which are stand-alone data structures capturing independent clinical statements about observations, diagnoses, allergies, medications, procedures, etc. This separation of concearns leverages a simple web architecture to enable a atomic creation and updates to these statements. (Contrast this with e.g. CCDA which defines a single document covering these different topics.) As of June 9, 2016, the development version of the FHIR core specification [[FHIR]] included 113 resources for the exchange of information about care plans, risk assessments, patients, organizations, appointments, observations, etc. along with a number of “container” resources such as Composition, Bundle and MessageHeader .

FHIR resources are defined using the FHIR StructureDefinition [[FHIRStructureDefintion]] resource, which provides the metamodel for all FHIR resources, including StructureDefinition itself. FHIR resource definitions are represented in a human readable form through a custom FHIR-specific representation on the FHIR web site. Alternative representations include customized XML and JSON templates and a Unified Modeling Language (UML)-like graphic format. A combination of XML Schema and Schematron provides a formal definition of the representation of FHIR data in XML.

Structure Definition

Structure Definitions enumerate sets of properties for abstract, hierarchical data structures. This captures structural constraints, such as the name and cardinality of properties, as well as definitions and meta data about properties. Structure Definitions can be textually represented in JSON or XML or graphically in HTML, as in this sample from FHIR Observation: [[FHIRObservation]]

NameType
✉ Observation DomainResource
├⧆ identifier Identifier*
├▭ status code1
├⧆ code CodeableConcept1
├☞ subject Reference(Patient | Group | Device | Location)?
├? effective[x] ?
│├▭ effectiveDateTimedateTime
│└⧆ effectivePeriodPeriod
└⧇ component BackboneElement*
 ├⧆ code CodeableConcept1
 ├? value[x] ?
 │├⧆ valueQuantityQuantity
 │├⧆ valueCodeableConceptCodeableConcept
 │└⧆ valuePeriodPeriod
 └⧆ dataAbsentReason CodeableConcept?

This can be read as a narrative:

Note also that clinical data statements include semantics which require rigorous examination during interpretation. In particular, properties like dataAbsentReason can change the interpretation of the data. This is monotonic, but requires that such fields always be checked when examining data.

The FHIR documentation includes RDF examples in [[Turtle]] and structural schemas in [[ShExSpec]]. The following is an example RDF graph which complies with the above excerpt of a FHIR StructureDefinition:

@prefix fhir: <http://hl7.org/fhir/> .
@prefix loinc: <http://loinc.org/owl#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix sct: <http://snomed.info/id/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

# - resource -------------------------------------------------------------------

<http://hl7.org/fhir/Observationblood-pressure> a fhir:Observation;
  fhir:nodeRole fhir:treeRoot;
  fhir:Resource.id [ fhir:value "blood-pressure"];
  fhir:Resource.meta [
     fhir:Meta.lastUpdated [ fhir:value "2014-01-30T22:35:23+11:00"^^xsd:dateTime ]
  ];
  fhir:DomainResource.text [
     fhir:Narrative.status [ fhir:value "generated" ];
     fhir:Narrative.div "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p>…</p></div>"
  ];
  fhir:Observation.identifier [
     fhir:index 0;
     fhir:Identifier.system [ fhir:value "urn:ietf:rfc:3986" ];
     fhir:Identifier.value [ fhir:value "urn:uuid:187e0c12-8dd2-67e2-99b2-bf273c878281" ]
  ];
  fhir:Observation.status [ fhir:value "final"];
  fhir:Observation.code [
     fhir:CodeableConcept.coding [
       fhir:index 0;
       fhir:concept loinc:55284-4;
       fhir:Coding.system [ fhir:value "http://loinc.org" ];
       fhir:Coding.code [ fhir:value "55284-4" ];
       fhir:Coding.display [ fhir:value "Blood pressure systolic & diastolic" ]
     ]
  ];
  fhir:Observation.subject [
     fhir:link <http://hl7.org/fhir/Patient/example>;
     fhir:Reference.reference [ fhir:value "Patient/example" ]
  ];
  fhir:Observation.effectiveDateTime [ fhir:value "2012-09-17"^^xsd:date];
  fhir:Observation.component [
     fhir:index 0;
     fhir:Observation.component.code [
       fhir:CodeableConcept.coding [
         fhir:index 0;
         fhir:concept loinc:8480-6;
         fhir:Coding.system [ fhir:value "http://loinc.org" ];
         fhir:Coding.code [ fhir:value "8480-6" ];
         fhir:Coding.display [ fhir:value "Systolic blood pressure" ]
       ], [
         fhir:index 1;
         fhir:concept sct:271649006;
         fhir:Coding.system [ fhir:value "http://snomed.info/sct" ];
         fhir:Coding.code [ fhir:value "271649006" ];
         fhir:Coding.display [ fhir:value "Systolic blood pressure" ]
       ]
     ];
     fhir:Observation.component.valueQuantity [
       fhir:Quantity.value [ fhir:value "107"^^xsd:decimal ];
       fhir:Quantity.unit [ fhir:value "mmHg" ];
       fhir:Quantity.system [ fhir:value "http://unitsofmeasure.org" ];
       fhir:Quantity.code [ fhir:value "mm[Hg]" ]
     ]
  ] .

<http://hl7.org/fhir/Patient/example> a fhir:Patient .

Note that this is an almost "maximal" example. An minimal example would include only the properties with a minimum cardinality of 1, e.g.

# - resource -------------------------------------------------------------------

<http://hl7.org/fhir/Observationblood-pressure> a fhir:Observation;
  fhir:nodeRole fhir:treeRoot;
  fhir:Observation.status [ fhir:value "final"];
  fhir:Observation.code [
     fhir:CodeableConcept.coding [
       fhir:index 0;
       fhir:concept loinc:55284-4;
       fhir:Coding.system [ fhir:value "http://loinc.org" ];
       fhir:Coding.code [ fhir:value "55284-4" ];
       fhir:Coding.display [ fhir:value "Blood pressure systolic & diastolic" ]
     ]
  ] .

The ShEx for the above StructureDefinition is:

PREFIX fhir: <http://hl7.org/fhir/> 
PREFIX fhirvs: <http://hl7.org/fhir/ValueSet/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> 
BASE <http://hl7.org/fhir/shape/>
start=<Observation> AND {fhir:nodeRole [fhir:treeRoot]}

# Measurements and simple assertions
<Observation> CLOSED {
    a [fhir:Observation];
    fhir:nodeRole [fhir:treeRoot]?;
    fhir:Resource.id @<id>?;                # Logical id of this artifact
    fhir:Resource.meta @<Meta>?;            # Metadata about the resource
    fhir:DomainResource.text @<Narrative>?;  # Text summary of the resource, for 
                                            # human interpretation 
    fhir:Observation.identifier @<Identifier>*;  # Unique Id for this particular 
                                            # observation 
    fhir:Observation.status @<code> AND
    	{fhir:value @fhirvs:observation-status};  # registered | preliminary | final | 
                                            # amended + 
    fhir:Observation.code @<CodeableConcept>;  # Type of observation (code / type)
    fhir:Observation.subject                # Who and/or what this is about
    (   @<PatientReference> OR
        @<GroupReference> OR
        @<DeviceReference> OR
        @<LocationReference>
    )?;
    (                                       # Clinically relevant 
                                            # time/time-period for observation 
        fhir:Observation.effectiveDateTime @<dateTime>  |
        fhir:Observation.effectivePeriod @<Period> 
    )?;
    fhir:Observation.component @<Observation.component>*;  # Component results
    fhir:index xsd:integer?                 # Relative position in a list
}

Note that this ShEx depends on other ShEx declarations such as Identifier, code, CodeableConcept.

Schema Mapping Strategy

StructureDefinitions are a domain-specific schema language in that they fully define the structural requirements of the abstract data model. The structural schema for the RDF representation is expressed in Shape Expressions. StructureDefinitions are mapped to Shape Expressions by defining a default interpretation of the constraints in StructureDefinitions as ShEx supplemented by specific mappings for all leaf nodes, CodeableConcepts, and Resource References.

FHIR Abstract Syntax

The structural components of StructureDefinitions can be represented with an abstract syntax:

StructureDefinition ::= name:string, type:FHIRResource|PrimativeType, declarations:List[PropertyDeclaration]
PropertyDeclaration ::= expr:PropertyExpression, cardinality:Cardinality
PropertyExpression  ::= PropertyChoice | BackboneElement | Property
PropertyChoice      ::= List[Property]
BackboneElement     ::= List[PropertyDeclaration]
Property            ::= name:string, type:FHIRResource|ResourceReference
ResourceReference   ::= reference:FHIRResource
Cardinality         ::= '?' | '1' | '+' | '*'
FHIRResource        ::= string
PrimativeType       ::= string

ShEx Abstract Syntax

The semantics of Shape Expressions is defined in terms of this abstract syntax, the relevent subset is exerpted here:

 ShapeDefinition  ::= label:string, shapeExpr:ShapeExpression
 ShapeExpression  ::= ShapeAnd | ShapeOr | Shape
 ShapeAnd         ::= shapeExprs:List[ShapeExpression]
 ShapeOr          ::= shapeExprs:List[ShapeExpression]
 Shape            ::= label:string, nodeConstraint:NodeConstraint*, expression:TripleExpression?
 TripleExpression ::= SomeOf | AllOf | TripleConstraint
 AllOf            ::= expressions:List[tripleExpression]
 SomeOf           ::= expressions:List[tripleExpression]
 TripleConstraint ::= predicate:URI, valueExpr:ShapeExpression
 NodeConstraint   ::= NodeKind|Datatype|Shape|XSDFacet

Default Mapping

Unless a more specific rule below applies, the DefaultMapping interpretation of a StructureDefinition as an RDF Schema is defined as follows:

Instance Mapping

...

Element

...

CodeableConcept

Resource Identity

Containment

Ordering

Profiles

Slicing

Invariants

Extensions

Extension Definition

Extension Structural Definition

TODO