This is the Continuous Integration Build of FHIR (will be incorrect/inconsistent at times).
See the Directory of published versions 
Responsible Owner: Implementable Technology Specifications Work Group | Standards Status: Normative |
![]() |
This page and the RDF Turtle forms are jointly maintained
by the HL7 FHIR project -- especially the
RDF subgroup |
FHIR resources can be represented as an RDF graph
serialized in the Turtle format
. The Turtle format is
defined to assist the process of bridging between operational
data exchange and formal knowledge processing systems. While the
Turtle form offers a fully functional representation of FHIR
resources, it has different operational characteristics from the
JSON and XML
representations, and would be used for different reasons.
Systems focused on operational exchange of data would not
usually choose to use Turtle.
This page describes:
The following Turtle prefixes are used in FHIR Turtle examples, the FHIR ontology, and the ShEx schema.
# These are typically used in FHIR Turtle data: @prefix fhir: <http://hl7.org/fhir/> . @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . @prefix owl: <http://www.w3.org/2002/07/owl#> . @prefix loinc: <http://loinc.org/rdf/> . # For LOINC codes @prefix sct: <http://snomed.info/id/> . # For SNOMED-CT codes # These are normally only used in the OWL ontology or ShEx schema: @prefix fhirvs: <http://hl7.org/fhir/ValueSet/> . @prefix fhirsd: <http://hl7.org/fhir/StructureDefinition/> . @prefix fhirw5: <http://hl7.org/fhir/w5#> . @prefix dc: <http://purl.org/dc/elements/1.1/> .
Each resource page has a set of language templates describing the FHIR expression in that language. The Turtle representation for a resource is described using this format:
[ a fhir:Observation; fhir:nodeRole fhir:treeRoot; # if this is the parser root # from Resource: fhir:id; fhir:meta; fhir:implicitRules; and fhir:language # from DomainResource: fhir:text; fhir:contained; fhir:extension; and fhir:modifierExtension fhir:identifier ( [ Identifier ] ... ) ; # 0..* Business Identifier for observation fhir:status [ code ]; # 1..1 registered | preliminary | final | amended ... fhir:code [ CodeableConcept ]; # 1..1 Type of observation (code / type) fhir:subject [ Reference(BiologicallyDerivedProduct|Device|Group...) ]; # 0..1 Who and/or what this is about fhir:encounter [ Reference(Encounter) ]; # 0..1 Healthcare event during which this observation is made # effective[x]: 0..1 Clinically relevant time/time-period for observation. One of these 4: fhir:effective [ a fhir:DateTime ; dateTime ]; fhir:effective [ a fhir:Period ; Period ]; fhir:effective [ a fhir:Timing ; Timing ]; fhir:effective [ a fhir:Instant ; instant ]; ... ]
Using this format:
0..1 indicates an
OPTIONAL element, i.e., minimum cardinality 0 and maximum
cardinality 1. Similarly 1..1
indicates a required element.0..* or
1..* indicates an
OPTIONAL or REQUIRED element (respectively) with no
maximum cardinality.Reference(BiologicallyDerivedProduct|Device|Group...)
means that it must be a
Reference
to a BiologicallyDerivedProduct,
or a Device,
or a Group, etc.# effective[x] indicates
a polymorphic property (see below),
whose value (in this example) may be a fhir:DateTime,
fhir:Period, fhir:Timing or fhir:Instant.
Note that examples in this specification show Turtle that is nicely formatted and well laid out, but that is not required or expected in conforming FHIR Turtle.
An example FHIR Turtle Observation illustrates the Turtle language and the additional conventions used by FHIR Turtle:
# bgpanel has type fhir:Observation
<http://hl7.org/fhir/Observation/bgpanel> a fhir:Observation ;
fhir:nodeRole fhir:treeRoot ; # and is the root of this document.
fhir:id [ fhir:v "bgpanel"] ; # Its id is bgpanel.
fhir:status [ fhir:v "final"] ; # It has an (extensible) status of final.
fhir:code [ # It has code,
fhir:coding ( [ # given by a list of Codings,
a loinc:34532-2 ; # each having an OPTIONAL concept IRI (see below)
fhir:system [ # plus a code system URI
fhir:l <http://loinc.org> ; # (as an OPTIONAL RDF node,
fhir:v "http://loinc.org"^^xsd:anyURI ] ; # but always as a literal),
# and a code:
fhir:code [ fhir:v "34532-2" ]
] )
] ;
fhir:subject [
fhir:l <http://hl7.org/fhir/Patient/infant> ;
fhir:reference [ fhir:v "Patient/infant" ]
] ; #
…
In this example,
is wrapped with '< ... >',fhir:Observation) and
following properties (e.g., fhir:status)
are prefixed names (like XML namespaced names),[ ... ]'s,"http://loinc.org"^^xsd:anyURI).FHIR Turtle imposes additional conventions to simplify recognition
and manipulation of FHIR RDF graphs. Although RDF graphs
in general may be serialized in any RDF format, FHIR RDF
mandates support specifically for Turtle
. All FHIR RDF
documentation is expressed in Turtle. And while the
standard media type for Turtle is text/turtle, the
use of Turtle for FHIR RDF uses the specialized media type application/fhir+turtle.
FHIR uses Shape
Expressions (ShEx)
to help define and validate FHIR RDF. See
fhir.shex
for the complete FHIR RDF schema. Each Resource page includes
a link for the subset of fhir.shex needed to describe that
Resource. The media type for ShEx is text/shex.
Each resource is represented as a set of RDF triples. When
a resource has a persistent identity (e.g., it can be found
at a particular URL -- usually a FHIR RESTful server), then
that URL is its identity. Resources with no persistent
identity (e.g., bundles from search results) have the
identity of the root document -- "<>" in Turtle syntax.
In the above example, the resource is the subject: <http://example.org/fhir/Observation/bgpanel>.
Some resources can contain other resources. Given that the
relationships can appear in any order in RDF, it cannot be
assumed that the first encountered element represents the
resource of interest that is being represented by the set of
Turtle statements. The focal resource -- the Resource that is not contained in any other Resource
-- is indicated by having a fhir:nodeRole property with a value
of fhir:treeRoot. If there is more than one
node labeled as a 'treeRoot' in a set of Turtle statements,
it may be impossible to deterimine which is the outermost
Resource.
Content within a resource is normally represented with
anonymous nodes (a/k/a "blank nodes"), unless something
else needs to reference that content. Normally only FHIR
Resource nodes are IRIs
. For example, this Turtle:
<http://example.org/fhir/Observation/bgpanel> fhir:status [ fhir:v "final" ]
asserts that:
<http://example.org/fhir/Observation/bgpanel>
has a status of some anonymous node."final" (a literal),
indicated by the fhir:v property.
(See Primitive Elements below.) Property names in FHIR RDF are shared across resources:
the same property may be used in several different resources.
For example, fhir:status is spelled
the same way
regardless of whether it appears in an Observation,
Diagnosis, or any other FHIR Resource.
Some properties are polymorphic within a resource:
the property may offer a choice of more than one
permissible object type.
If the Structure tab in a resource's
HTML page shows "[x]" next to a property, such as
value[x],
then that property is polymorphic in FHIR RDF.
(Alternatively, if the type
property in the resource's structure definition shows
a list of two or more types for a given property's value,
then the property is polymorphic in FHIR RDF. For example, see the
value property in
Observation's JSON structure definition.)
In other formats (XML, JSON), a FHIR property with a choice
of value types has the type appended to the property name,
e.g., valueQuantity if the value is a
Quantity (i.e., Observation.valueQuantity).
But in FHIR RDF, it is written as a polymorphic fhir:value property,
and the object asserts its type explicitly, as shown in the
following excerpt from an Observation body weight example.
Confusingly, this excerpt happens to include a second (nested) fhir:value
property, which is a property of the
Quantity datatype (i.e., Quantity.value),
and whose type
is indicated directly by the xsd:decimal datatype attached to
its fhir:v literal value.
fhir:value [ # From Observation.value[x] (Observation.valueQuantity)
a fhir:Quantity ;
fhir:value [ fhir:v "185"^^xsd:decimal ] ; # From Quantity.value
fhir:unit [ fhir:v "lbs" ] ;
fhir:system [ fhir:l <http://unitsofmeasure.org> ;
fhir:v "http://unitsofmeasure.org"^^xsd:anyURI ] ;
fhir:code [ fhir:v "[lb_av]" ]
] ;
While RDF property names are case-sensitive, FHIR avoids confusion by assuring that there are no properties that differ only in case.
Elements that can repeat are represented with RDF lists
(officially called "RDF collections") in order to retain the
order of their elements. For example this
fhir:coding property holds a list of two members:
fhir:coding (
[ a <http://loinc.org/rdf/29463-7> … ]
[ a <http://loinc.org/rdf/3141-9> … ]
)
Since RDF lists can cause problems for OWL users, a
script
can
convert RDF lists to an alternate representation.
See Using FHIR RDF with OWL for more info.
Primitive elements -- elements with a primitive type -- are represented as anonymous nodes, both so that extensions can be attached and so that they can be consistently treated as OWL object properties (versus sometimes being datatype properties). Inside the anonymous node:
rdf:type (or
a
in Turtle shorthand) if it is not implied
by the property whose value is being represented. See
Property Names and Polymorphism
for more explanation.fhir:Code . This is done to avoid
having a name clash with the
fhir:code property, since RDF is
case sensitive. For consistency, the RDF class name for the FHIR
xhtml
is also capitalized fhir:Xhtml
even though it is technically a
special type.
All other FHIR RDF names use the same
capitalization conventions as in the FHIR content model,
JSON and XML.
,
written with an xsd: or
xs: prefix,
or an RDF datatype.fhir:v property, which is the
only FHIR property that directly holds an RDF literal -- i.e.,
it is the only OWL datatype property in FHIR RDF -- and
it always holds an RDF Literal.fhir:v literal has two parts:
a quoted string that contains
the value, and an XSD or RDF type:fhir:v "[value]"^^xsd:type
The XSD type is one of the following
XML Schema Datatypes (XSD)
, typically written with an xsd: or xs: prefix:
boolean
,
integer
,
decimal
,
base64Binary
,
dateTime
,
date
,
gYear
,
gYearMonth
or
time
.
RDF type rdf:XMLLiteral is used
for values of FHIR type xhtml.
For example, a value of FHIR type
positiveInt
is an anonymous node with a
fhir:v assertion and possibly a
type assertion, like one of the following:
[ fhir:v "2"^^xsd:positiveInteger ] # With implied FHIR type
[ a fhir:PositiveInt ; fhir:v "2"^^xsd:positiveInteger ] # With explicit FHIR type
The fhir:v property can never be empty. Either the
relationship is absent, or it is present with at least one
character of content. XHTML is represented as an escaped
xsd:string.
Some FHIR primitive datatypes are defined as a union of multiple XML Schema datatypes:
In such cases, the correct XSD type
must be determined by inspecting the literal value for
conformance with one of the union XSD types for that FHIR type.
For example, since a FHIR decimal
is a union of xsd:decimal
and xsd:double
,
any value with an 'e' or 'E' in it is an xsd:double, otherwise it
is an xsd:decimal. For example, for a property whose value
is a FHIR decimal,
an literal value of "185" must be given the XSD datatype xsd:decimal
because it does not contain 'e' or 'E'.
Values of other FHIR union types --
date or dateTime
must be handled similarly, to assign the most specific XSD type
that matches the given literal value.
Literal values that can be represented using Turtle shorthand notation for xsd:string, xsd:integer, xsd:decimal, xsd:double or xsd:boolean MAY optionally use shorthand instead of the long form described above. However, authors of FHIR Turtle serializers are advised to be aware that there are some differences between what is permitted in FHIR, Turtle shorthand, and XSD literals, and these differences can affect Turtle serialization of FHIR. For example:
in Turtle. Turtle shorthand for an xsd:decimal value
requires a decimal point, whereas the xsd:decimal type does not.
Therefore, a FHIR decimal
value of 185 must either have a decimal point explicitly
added, like 185.0, or the type must be explicitly indicated,
like "185"^^xsd:decimal.
Otherwise 185 in Turtle would be parsed as an xsd:integer.
does. To facilitate linkage in RDF graphs,
if a primitive has FHIR type uri
or one of its subtypes (url, canonical, uuid, oid), then
a fhir:l property --
previously called fhir:link, in FHIR R5 --
is RECOMMENDED as a sibling of the
fhir:v property.
The value of the fhir:l property is
an RDF node having the same URI as the URI given in the
fhir:v property, with one exception.
If the fhir:v URI contains a
vertical bar ("|", aka pipe symbol) then it represents a
version indicator, which is stripped off and converted into
a "?version=" query string, like this:
<http://example.org/fhir/MeasureReport/measurereport-cms146-cat3-example> fhir:measure [
a fhir:Canonical ;
fhir:l <http://example.org/fhir/Measure/CMS146?version=v123> ;
fhir:v "http://example.org/fhir/Measure/CMS146|v123"^^xsd:anyURI ;
] ;
A Reference element is represented using the same rules as above:
fhir:subject [
# a fhir:Reference ;
fhir:reference [ fhir:v "Patient/example" ];
fhir:display [ fhir:v "Example Patient" ];
];
This allows faithful round tripping of the resource between the Turtle format and the JSON and XML formats. However, it's very useful for an RDF processor if the RDF graph links to the target of the reference directly. This can be represented using the OPTIONAL fhir:l property:
fhir:subject [
# a fhir:Reference ;
fhir:l <http://example.org/fhir/Patient/example> ;
fhir:reference [ fhir:v "Patient/example" ];
fhir:display [ fhir:v "Example Patient" ];
];
The correct value for the fhir:l relationship must be
determined by resolving the rules
for resolving references, for the various reference
types, to a literal URL that refers to the correct content in
the local RDF context. Although the target type of the
fhir:reference property is specified
as xsd:string, it is
required to be an absolute or relative URI or fragment
identifier, so it can always be used for a fhir:l link.
The fhir:l relationship can be added automatically as part of generating the resource representation, or it can be injected by a post-processor that knows how to convert the raw references into RDF-suitable references.
Inline resources -- when a resource is contained directly in another element -- occur in the following places:
The following example (derived from
this example) shows a
Bundle. The Bundle holds a list
of fhir:entrys, each of which specifies
a Resource that is a member of that Bundle. Although Turtle
serializes each Resource separately, they are logically all
part of the same Bundle.
# This is the parent Bundle resource:
<http://hl7.org/fhir/Bundle/bundle-references> a fhir:Bundle ;
fhir:nodeRole fhir:treeRoot ;
fhir:id [ fhir:v "bundle-references"] ;
fhir:type [ fhir:v "collection"] ;
fhir:entry ( [
fhir:fullUrl [
fhir:l <http://example.org/fhir/Patient/23> ;
fhir:v "http://example.org/fhir/Patient/23"^^xsd:anyURI ] ;
fhir:resource <http://example.org/fhir/Patient/23>
] )
…
# This is a member of the above Bundle:
<http://example.org/fhir/Patient/23> a fhir:Patient ;
fhir:id [ fhir:v "23"] ;
fhir:text [
fhir:status [ fhir:v "generated" ] ;
fhir:div [ fhir:v "…"^^rdf:XMLLiteral ]
] ;
fhir:identifier ( [
fhir:system [
fhir:l <http://example.org/ids> ;
fhir:v "http://example.org/ids"^^xsd:anyURI ] ;
fhir:value [ fhir:v "1234567" ]
] ) .
Except for transactions and batches, each entry in a Bundle has a URI that is determined from its fhir:fullUrl property as described in Resolving references in Bundles. Systems are responsible for ensuring a unique mapping from fullUrl to Resource, including in the case of multiple versions of a resource.
When parsed into RDF, all URIs are absolute, e.g., http://example.org/some/path.ext.
The Turtle syntax for RDF leverages the same relative URL resolution
as HTML.
The FHIR examples (available from the downloads page) and this document follow some conventions described below with the goal of
URLs are constructed from the fhir:id property if it is given in the example.
These are presumed to be Resources in a server compliant with the FHIR REST API served from http://example.org/.
Thusly, a PlanDefinition with id "KDN5" is assumed to have a URL of http://example.org/PlanDefinition/KDN5.
If a contained resource has a fhir:id property, then its value MAY be used in generating a URI for that contained resource, following rules for Contained Resources. Local references (i.e., starting with "#") are relative to the parent (containing) resource. If the example does not include a containing Resource with an apparent URL, we will represent that resource's URI in Turtle as a relative URI.
In the following example (derived from the KDN5 example), the FHIR id is given ("KDN5") so we assume a base URL of http://example.org/PlanDefinition/KDN5.
The contained resource (having fhir:id "1111") is given a URL relative to that base.
As in HTML, a "#" character is prepended to the child's fhir:id when it is used as a local reference.
Given the asssumed base, the contained ActivityDefintion and the fhir:l and fhir:contained properties which reference it could be written as <#1111> but they are resolved here to their absolute URI, <http://example.org/PlanDefinition/KDN5#1111> for clarity:
# KDN5 is the parent resource in this example:
<http://example.org/PlanDefinition/KDN5> a fhir:PlanDefinition ; # Known URI
fhir:nodeRole fhir:treeRoot ;
fhir:id [ fhir:v "KDN5"] ;
# fhir:contained gives a list of resources that are logically contained
# inside this (KDN5) resource, though Turtle serializes them separately:
fhir:contained ( <http://example.org/PlanDefinition/KDN5#1111> ) ; # assertion of containership
fhir:action ( [
fhir:textEquivalent [ fhir:v "Gemcitabine 1250 mg/m² IV over 30 minutes on days 1 and 8" ] ;
fhir:definition [
a fhir:Canonical ;
# Here the KDN5 parent references the contained resource:
fhir:l <http://example.org/PlanDefinition/KDN5#1111> ; # use of the contained Resource
fhir:v "#1111"^^xsd:anyURI ; # Local reference starts with "#"
]
] ) ;
…
# The definition of the (logically) contained resource #1111 is here:
<http://example.org/PlanDefinition/KDN5#1111> a fhir:ActivityDefinition ;
fhir:id [ fhir:v "1111" ] ; # Local identifier
fhir:status [ fhir:v "draft" ] .
…
In contrast, in the following example, the parent does not have an id so we would need information to know how this Resource is uniquely addressed.
In the absense of that information, we will simply express the contained Resource as a relative URL, <#2222>, with an unstated base.
# KDN5 is the parent resource in this example:
<> a fhir:PlanDefinition ; # URI is relative to unspecified base URI
fhir:nodeRole fhir:treeRoot ;
# fhir:contained gives a list of resources that are logically contained
# inside this (KDN5) resource, though Turtle serializes them separately:
fhir:contained ( <#2222> ) ; # Relative URI
fhir:action ( [
fhir:textEquivalent [ fhir:v "Gemcitabine 1250 mg/m² IV over 30 minutes on days 1 and 8" ] ;
fhir:definition [
a fhir:Canonical ;
# Here the KDN5 parent references the contained resource:
fhir:l <#2222> ;
fhir:v "#2222"^^xsd:anyURI ; # Local reference starts with "#"
]
] ) ;
…
# The body of the (logically) contained resource 2222 is here, and receives
# a URI derived from its parent's URI:
<#2222> a fhir:ActivityDefinition ;
fhir:id [ fhir:v "2222" ] ; # Local identifier
fhir:status [ fhir:v "draft" ] .
…
The same logic applies to the Coding data type. These
are represented directly in Turtle by serializing their
properties as above.
However, for reasoners using the RDF graph, it's also useful to
make the implicit concept references in these Codings
explicit, by specifying an OPTIONAL concept IRI
in an
rdf:type assertion, written using shorthand a in
Turtle:
fhir:code [
fhir:coding (
[
a loinc:29463-7; # OPTIONAL, but RECOMMENDED
fhir:system [ fhir:v "http://loinc.org" ];
fhir:code [ fhir:v "29463-7" ];
fhir:display [ fhir:v "Body Weight" ]
]
[
a sct:27113001; # OPTIONAL, but RECOMMENDED
fhir:system [ fhir:v "http://snomed.info/sct" ];
fhir:code [ fhir:v "27113001" ];
fhir:display [ fhir:v "Body weight" ]
]
)
];
A concept IRI
uniquely identifies a concept that would otherwise
be identified by a <Coding.system, Coding.code> pair. A concept
IRI normally has two parts -- an IRI stem and a code --
though concept IRIs that do not follow this pattern can be used.
An IRI stem is the initial substring of the concept IRIs
that correspond to all codes in a particular Code System or terminology.
The concept IRI is formed by concatenating the IRI stem with
the code (after percent-encoding any reserved characters
-- see Appendix 1: Algorithm for Creating a Concept IRI
for details). The IRI stem is typically used to define an
IRI prefix in Turtle and SPARQL, such as loinc: or sct: in
the above example. This approach allows the Compact URI
loinc:29463-7 (in Turtle or SPARQL) to be easily translated into the
concept IRI http://loinc.org/rdf/29463-7 by concatenating
the IRI stem http://loinc.org/rdf/ with the code
29463-7. This particular IRI stem is defined in the
LOINC User Guide S12.7.2
.
Compact URIs ("CURIEs")
provide a mechanism for abbreviating IRIs using
a prefix and a reference, separated by a colon, such as
loinc:29463-7.
Although some RDF systems have treated CURIEs
directly as FHIR Codes -- i.e., including the "loinc:" prefix as part of the code --
non-prefixed FHIR codes like 29463-7 are strongly
preferred because they align better with the use of IRI stems
described herein.
If the "loinc:" prefix were treated as part of the FHIR code,
like loinc:29463-7, then when the
IRI stem is prepended the resulting absolute IRI would become
http://loinc.org/rdf/loinc:29463-7,
which in this example would be incorrect for
the intended LOINC concept.
One might wonder why the Coding.system is not used directly
as the IRI stem for a given terminology. One reason is that
Coding.systems often lack a convenient separator
character as their final character, such as "/" or "#", which
could cause problems if they were directly concatenated with codes,
leading to erroneous concept IRIs such as http://loinc.org35217-9.
But the main reason is that the Coding.system and the IRI stem of some terminologies
were chosen independently and differ in unpredictable ways.
Hence, there is no simple formula for determining the correct
IRI stem from a Coding.system.
To address this problem, and to facilitate ease of use,
HL7 maintains a mapping from Coding.systems
to IRI stems: IRI stems can be registered and looked
up in the
HL7 Terminology (THO) website
,
based on the desired Coding.system.
To look up the correct IRI stem for a given terminology,
such as LOINC:
;
; then
,
and look for the "IRI stem" entry: http://loinc.org/rdf/ .
If an IRI stem for a Coding.system is published at
https://terminology.hl7.org/
it SHOULD be used. An NPM
package is also available to efficiently automate lookup of
IRI stems from Coding.systems.
To add an IRI stem to that site,
see Appendix 2: Registering an IRI Stem on the HL7 Terminology Website.
A Resource might have any number of non-modifier extensions, represented as an RDF list like this:
<http://example.org/fhir/MedicationRequest/MR321> a fhir:Observation;
fhir:nodeRole fhir:treeRoot;
fhir:extension (
[ fhir:url [
fhir:l <http://example.org/fhir/StructureDefinition/observation-bodyPosition> ;
fhir:v "http://example.org/fhir/StructureDefinition/observation-bodyPosition"^^xsd:anyURI ] ;
fhir:value [
fhir:coding (
a sct:33586001;
fhir:system [ fhir:l <http://snomed.info/sct> ;
fhir:v "http://snomed.info/sct"^^xsd:anyURI ];
fhir:code [ fhir:v "33586001" ];
fhir:display [ fhir:v "Sitting position (finding)" ]
) ] ]
[ fhir:url [
fhir:l <http://example.org/fhir/StructureDefinition/observation-delta> ;
fhir:v "http://example.org/fhir/StructureDefinition/observation-delta"^^xsd:anyURI ] ;
fhir:value [
fhir:coding (
a sct:1250004;
fhir:system [ fhir:l <http://snomed.info/sct> ;
fhir:v "http://snomed.info/sct"^^xsd:anyURI ];
fhir:code [ fhir:v "1250004" ];
fhir:display [ fhir:v "Decreased (qualifier value)" ]
) ] ]
)
…
A primitive element such as fhir:birthDate can have a list of extensions attached like this:
…
fhir:birthDate [
fhir:v "2016-05-18"^^xsd:date ;
fhir:extension ( [
fhir:url [
fhir:l <http://hl7.org/fhir/StructureDefinition/patient-birthTime> ;
fhir:v "http://hl7.org/fhir/StructureDefinition/patient-birthTime"^^xsd:anyURI ] ;
fhir:value [
a fhir:DateTime ;
fhir:v "2016-05-18T10:28:45Z"^^xsd:dateTime
]
] )
]
See Extensibility for additional guidance on FHIR extensibility.
FHIR allows modifierExtensions
on DomainResources,
BackboneElements
and BackboneTypes.
The type of any DomainResource with any modifierExtension
is prefixed with '_' in RDF.
The '_' prefix helps prevent FHIR RDF
processors that do not understand a particular modifier
extension from blindly processing it as though it still had
the original semantics. The structure of the
element is otherwise unchanged. Note the underscore at the
beginning of "_MedicationRequest" in the following example:
<http://example.org/fhir/MedicationRequest/MR321> a fhir:_MedicationRequest;
fhir:nodeRole fhir:treeRoot;
fhir:extension ( ... ); # above bodyPosition and delta extensions
fhir:modifierExtension (
[
fhir:url [
fhir:l <http://example.org/fhir/StructureDefinition/anti-prescription> ;
fhir:v "http://example.org/fhir/StructureDefinition/anti-prescription"^^xsd:anyURI ] ;
fhir:value [ a fhir:Boolean ; fhir:v true ]
]
)
…
The FHIR ontology includes a
fhir:modifierExtensionClass property
that relates each unmodified resource class to its corresponding
modified resource class, so that SPARQL queries can easily
find all modified classes without having to parse their URIs
to look for the leading underscore:
fhir:MedicationRequest fhir:modifierExtensionClass fhir:_MedicationRequest .
BackboneElements and BackboneTypes are object types. Any RDF property that references a modified BackboneElement or BackboneType is prefixed with a '_'. Note the underscore at the beginning of "_value" in the following example:
<http://example.org/fhir/Observation/Obs123> a fhir:Observation;
…
fhir:_value [
a fhir:Quantity;
fhir:value [ fhir:v "185"^^xsd:decimal ];
fhir:unit [ fhir:v "lbs" ];
fhir:system [
fhir:l <http://unitsofmeasure.org> ;
fhir:v "http://unitsofmeasure.org"^^xsd:anyURI
];
fhir:code [ fhir:v "[lb_av]" ];
fhir:modifierExtension (
[
fhir:url [
fhir:l <http://example.org/fhir/StructureDefinition/anti-observation> ;
fhir:v "http://example.org/fhir/StructureDefinition/anti-observation"^^xsd:anyURI ] ;
fhir:value [ a fhir:Boolean ; fhir:v true ]
]
) ;
]
The FHIR ontology also includes a
fhir:modifierExtensionProperty property
that relates each unmodified property to its corresponding modified property:
fhir:value fhir:modifierExtensionProperty fhir:_value .
See Modifier Extensions for additional requirements around modifier extensions.
To facilitate FHIR RDF creation and processing, the following
additional artifacts are available from the
downloads page. While the
fhir.hl7.org site
holds the official released versions of these artifacts, unreleased
INFORMATIVE versions may also be available from the
build.fhir.org site
.
ShEx schema fhir.shex (NORMATIVE). This schema is intended to help users validate FHIR RDF data. It is normative in the sense that if some purported FHIR RDF data is inconsistent with the ShEx schema, then that data is known to be invalid. However, consistency with the ShEx schema does not guarantee that the data is fully valid, because there are additional semantic requirements of FHIR data that are not captured in the ShEx schema.
Although the logical meaning of the ShEx schema is normative, the expression of that meaning is INFORMATIVE (i.e., not normative): it MAY be changed or enhanced at any time. For example, the schema MAY be refactored, or shape names that only appear in the ShEx MAY change.
OWL Ontology fhir.ttl (NORMATIVE). This describes the classes and properties that are used to represent FHIR RDF data. It is normative in the sense that if an OWL reasoner finds some purported FHIR RDF data to be logically inconsistent with the ontology, then that data is known to be invalid, i.e., not conforming to the FHIR specification. However, consistency with the ontology does not guarantee that the data is fully valid, because there are many requirements of FHIR data that are not captured in the ontology.
Although the logical meaning of the OWL ontology is normative, its expression in OWL/Turtle is INFORMATIVE (i.e., not normative): it MAY be changed or enhanced at any time. For example, it MAY be refactored, or class or property names that only appear in the ontology MAY change.
W5 Ontology w5.ttl (INFORMATIVE). This ontology attempts to capture relationships expressed in the Five Ws Mappings (formerly called W5 Report) -- Who, What, When, Where, Why. It has not been well vetted, and MAY be changed at any time.
v3 RIM ontology rim.ttl (INFORMATIVE).
This ontology attempts to capture semantic relationships between
HL7 v3 RIM
and FHIR. It has not been well vetted, and may be
changed at any time.
Application developers wishing to use FHIR RDF will often need to perform the following rough steps, though exact steps will depend on your application:


is a handy browser-based tool for experimenting with
conversion of FHIR JSON to FHIR RDF. It is not for
production use.
,
in case new implementations have become available.
.)
. You can download the ShEx schema for FHIR RDF.
OWL Caveat: RDF lists use a ladder of rdf:first and rdf:rest properties.
This can cause problems in OWL DL, which disallows axioms
over the rdf: namespace. To work around this problem, OWL users
can convert RDF lists in their FHIR data to a different list
representation.
A script
is available for doing such a conversion.
This page documents an RDF format that can be used to exchange FHIR data, on the basis that RDF is a universal information representation. Using RDF enables FHIR data to be used with other RDF data and RDF-aware applications to support inference, shared semantics across multiple standards and data formats, data integration, semantic data validation, compliance enforcement, SPARQL queries and other uses. Implementers using FHIR in this fashion are advised to be aware of the relationship between FHIR's RDF format and other uses of ontologies.
FHIR's RDF format is based on the same abstract information
model as the XML and JSON formats and carries the same
information content. Resources are losslessly round-trippable
between XML, JSON and RDF formats and data expressed in the
RDF format corresponds closely to the XML and JSON formats in
its look and feel, though a few additional FHIR-specific terms
appear in the RDF format, as explained above:
fhir:nodeRole, fhir:treeRoot and
fhir:v.
In addition to defining the RDF format, this specification provides an associated ontology containing formal definitions of the classes and properties that appear in the RDF format. Ontologies that were designed independently almost always have some impedance mismatch when attempting to use them together. Many of the ontologies in the medical and life sciences domain are designed to capture facts about the world for research, such as the fact that the mitral valve is a kind of heart valve. But FHIR was designed to support the day-to-day operations of healthcare providers exchanging electronic health records (EHRs), and in this context, the orientation has historically been different. When using FHIR RDF with other ontologies, impedance differences are likely to show up in two main ways:
For both of these reasons, to maintain monotonicity in RDF, users are advised to avoid directly interpreting FHIR RDF as stating facts. Transformations may be needed to remove or isolate non-monotonic elements and reconcile the records across time and perspective.
Application developers are also advised to be aware that some FHIR
data attributes have a major impact on the interpretation of
the enclosing data element: the meaning of the enclosing
element cannot be determined in isolation. For example, a
status of 'entered-in-error' means that the resource was
created accidentally and is not clinically relevant.
Slides
by Eric Prud'hommeaux
illustrate how
inference can be used on FHIR RDF data to perform a query for
FHIR Observations of rheumatoid arthritis, using the SNOMED-CT
ontology
. Caveat: These slides were based on an earlier
version of FHIR, so some specifics may have changed.
A webinar
by Harold Solbrig
shows how FHIR RDF data can be used with
the SNOMED-CT
ontology
to recognize a cancer diagnosis. An associated
tutorial
details the steps used. Caveat: This
webinar and tutorial were based on a previous version of FHIR RDF,
so some specifics may have changed.
For background on concept IRIs, IRI stems, and their relationship to Code Systems, see Concept IRIs and IRI Stems above.
This section defines a standard algorithm for generating a
Concept IRI from a <Coding.system, Coding.code>
pair. In many cases it involves merely concatenating the
associated IRI Stem with the Coding.code.
But because a Coding.code could contain reserved
characters that are used to delineate different parts of the
IRI, percent-encoding of reserved characters is required, as
defined below.
Given:
Coding.system, s, that
identifies a terminology t; and Coding.code, c, that is defined
within t;a Concept IRI, conceptIRI, corresponding to s
and c is computed as follows:
, then conceptIRI is undefined. Halt.
urn:ietf:rfc:3987, then conceptIRI is c,
and c MUST be a syntactically valid absolute-IRI as
defined by RFC
3987
. Halt. (Informative comments: The
purpose of this special case is to permit System.codes
that are already IRIs to be used directly as Concept IRIs,
without any transformation. Note that an absolute-IRI may
also be a URL or a URN.)
, quoted here for convenience (informative):The IRI-safe version of a string is obtained by applying the following transformation to any character that is not in the iunreserved productionThe iunreserved production defined in RFC 3987, section 2.2in [RFC3987]:
1. Convert the character to a sequence of one or more octets using UTF-8 [RFC3629]
2. Percent-encodeeach octet [RFC3986]
using ABNF
is also quoted here for convenience (informative):The ucschar production defined in RFC 3987, section 2.2iunreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" / ucschar
is also quoted here
for convenience (informative). (Informative comment: The ucschar
production defines international character ranges that are
valid Unicode characters within the intersection of path
components (ipath), query strings (iquery) and fragment
identifiers (ifragment). They do not include any
reserved characters involved in parsing apart the various
components of an IRI.)ucschar = %xA0-D7FF / %xF900-FDCF / %xFDF0-FFEF
/ %x10000-1FFFD / %x20000-2FFFD / %x30000-3FFFD
/ %x40000-4FFFD / %x50000-5FFFD / %x60000-6FFFD
/ %x70000-7FFFD / %x80000-8FFFD / %x90000-9FFFD
/ %xA0000-AFFFD / %xB0000-BFFFD / %xC0000-CFFFD
/ %xD0000-DFFFD / %xE1000-EFFFD
|
|
IRI Stem |
|
Concept IRI |
|
ICD 10: |
|
|
|
|
SNOMED CT:* |
|
|
|
|
MeSH: |
|
|
|
|
LOINC: |
|
|
|
|
Example coding system that uses a Unicode smiling
face character (U+263A) as a code: |
|
|
|
|
Example coding system that uses a Unicode waving hand
character (U+1F44B) from the Miscellaneous
Symbols and Pictographs |
|
|
|
*As of this writing (5-Sep-2022) it is not clear what IRI stem is most appropriate when writing a SNOMED CT post-coordinated code expression.
This section is intended for those who are helping to add or
maintain IRI stem registrations at the
HL7 Terminology website
.
IRI stems have not been standardized for all FHIR
Coding.systems. But any that have been
standardized SHOULD be registered in the HL7 terminology
website by adding appropriate CodeSystem and NamingSystem
entries, using the system "urn:ietf:rfc:3987" and
identifier type
of "iri-stem". You can see an
example of this in the HL7 description of the
LOINC CodeSystem
and the
LOINC NamingSystem
.
Assuming that the Coding.system
for your desired IRI stem has already been registered, the
process for registering an IRI stem for it includes:
,
prefix.cc
,
OBO Foundry
or Wikidata
(by means of wdt:P1921
).
. This means that the IRI stem
MUST start with a "scheme:" string, such as "http:",
"https:", "urn:" or any other valid scheme, followed by an
authority, followed by any number of path parts and an OPTIONAL
query and fragment. Examples of valid IRI stems include:
doi:10.1111/urn:loinc.org: ← Note the trailing colon (":")http://loinc.org/rdf/http://purl.obolibrary.org/obo/HP_ ← Note the trailing underscore ("_")https://example.org/terminologies/?action=search&id=ftp://user@example.org:2222/loinc/gen-delims or sub-delims productions from
section 2.2 of RFC 3987
or one of the characters "-", ".", "_"
or "~") . An IRI stem that ends with an alphanumeric
character is likely to have the meaning of the final term
altered when the code is concatenated. For example, an IRI
stem of "http://example.org" when concatenated with the code
"39" will result in a concept IRI of "http://example.org39",
which is probably not the concept IRI intended.
On the HL7 Terminology website (https://terminology.hl7.org
),
add the IRI stem to the NamingSystem and CodeSystem records
corresponding to the desired Coding.system, by following the
process for submitting a UTG change proposal
. The IRI stem
SHOULD be added to both the NamingSystem and the CodeSystem.
Additions, deletions and modifications of an IRI stem to
an existing NamingSystem or CodeSystem will generally be
considered a minor change under the UTG Versioning policy
.
As of this writing (17-Dec-2022), the change proposal
process for doing this included the following steps. However,
since the process may have later changed, readers are advised to
verify it
prior to proceeding. You can also see an example of such
a change proposal, including the associated changes in the
XML files, in the MeSH IRI stem change proposal
.
for an issue titled "Registering an IRI Stem (RDF Subgroup)".
with that title, describing how to improve the above steps.