This page is part of the FHIR Specification (v1.1.0: STU 3 Ballot 1). 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 R3 R2
This is a frozen snapshot of the FHIR specification created for the purpose of balloting the GAO implementation Guide. It includes draft changes that may be part of the future DSTU 2.1 release but further change is expected. Readers should focus solely on the GAO implementation content, and FHIR DSTU 2 for other purposes.
FHIR Infrastructure ![]() | Maturity Level: N/A | Ballot Status: DSTU 2 |
One common use of slicing is to describe different constraints on different kinds of patient contact details. In this example, as Patient.telecom is defined as: ContactPoint [0..*] where the ContactPoint has system, value and use.
Consider the case where the profile should say:
An example of a patient resource that meets these rules:
<Patient> ... snip ... <telecom> <system value="phone" /> <use value="home" /> <value value="5551234567" /> </telecom> <telecom> <system value="email" /> <value value="someone@acme.org" /> </telecom> ... snip ... </Patient>
To do this, the profile that implements these rules needs to do the following:
In a StructureDefinition, this will look like:
<!-- setting up the slicing --> <element> <path value="Patient.telecom"/> <slicing> <discriminator value="system"/> <discriminator value="use"/> <rules value="closed"/> </slicing> <!-- net cardinality rules --> <min value="1"/> <max value="3"/> </element> <!-- first slice: home phone --> <element> <path value="Patient.telecom"/> <name value="HomePhone"/> <!-- mandatory - gives the slice a name --> <min value="1"/> <max value="1"/> </element> <element> <path value="Patient.telecom.system"/> <min value="1"/> <fixedCode value="phone"/> </element> <element> <path value="Patient.telecom.value"/> <min value="1"/> </element> <element> <path value="Patient.telecom.use"/> <min value="1"/> <fixedCode value="home"/> </element> <!-- second slice: work phone --> <element> <path value="Patient.telecom"/> <name value="WorkPhone"/> <!-- mandatory - gives the slice a name --> <min value="0"/> <max value="1"/> </element> <element> <path value="Patient.telecom.system"/> <min value="1"/> <fixedCode value="phone"/> </element> <element> <path value="Patient.telecom.value"/> <min value="1"/> </element> <element> <path value="Patient.telecom.use"/> <min value="1"/> <fixedCode value="work"/> </element> <!-- third slice: email --> <element> <path value="Patient.telecom"/> <name value="Email"/> <!-- mandatory - gives the slice a name --> <min value="0"/> <max value="1"/> </element> <element> <path value="Patient.telecom.system"/> <min value="1"/> <fixedCode value="email"/> </element> <element> <path value="Patient.telecom.value"/> <min value="1"/> </element> <element> <path value="Patient.telecom.use"/> <min value="0"/> </element>
Note: lots of definition detail has been left out, and only the parts relevant to the pattern are shown. Also, providing a fixed value makes the minimum cardinality irrelevant, but it is shown here for completeness.
This table illustrates the relationship between the instance and the ElementDefinitions:
Path | Name | Min | Max | Fixed | |
<Patient> | Patient | ||||
Patient.telecom | 1 | 3 | |||
<telecom> | Patient.telecom | HomePhone | 1 | 1 | |
<system value="phone" /> | Patient.telecom.system | 1 | 1 | phone | |
<value value="5551234567" /> | Patient.telecom.value | 1 | 1 | ||
<use value="home" /> | Patient.telecom.use | 1 | 1 | home | |
</telecom> | |||||
Patient.telecom | WorkPhone | 0 | 1 | ||
<telecom> | Patient.telecom | 0 | 1 | ||
<system value="email" /> | Patient.telecom.system | 1 | 1 | ||
<value value="someone@acme.org" /> | Patient.telecom.value | 1 | 1 | ||
</telecom> | Patient.telecom.use |
Another use of Slicing is for Blood Pressure Measurements, where the profile says:
An example of an Observation resource that meets these rules:
<Observation> ... snip ... <component> <code> <coding> <system value="http://loinc.org" /> <code value="8480-6" /> <display value="Systolic blood pressure" /> </coding> </code> <valueQuantity> <value value="120" /> <unit value="mmHg" /> <system value="http://unitsofmeasure.org" /> <code value="mm[Hg]" /> </valueQuantity> </component> <component> <code> <coding> <system value="http://loinc.org" /> <code value="8462-4" /> <display value="Diastolic blood pressure" /> </coding> </code> <valueQuantity> <value value="80" /> <unit value="mmHg" /> <system value="http://unitsofmeasure.org" /> <code value="mm[Hg]" /> </valueQuantity> </component> </Patient>
To do this, the profile that implements these rules needs to do the following:
In a StructureDefinition, this will look like:
<!-- setting up the slicing --> <element> <path value="Observation.component"/> <slicing> <discriminator value="code"/> </slicing> <!-- net cardinality rules --> <min value="2"/> <max value="*"/> </element> <!-- first slice: systolic --> <element> <path value="Observation.component"/> <name value="systolic"/> <!-- mandatory - gives the slice a name --> <min value="1"/> <max value="1"/> </element> <element> <path value="Observation.component.code"/> <min value="1"/> <fixedCodeableConcept> <coding> <system value="http://loinc.org" /> <code value="8480-6" /> <display value="Systolic blood pressure" /> </coding> </fixedCodeableConcept> </element> <element> <path value="Observation.component.valueQuantity"/> <min value="1"/> </element> <!-- second slice: diastolic --> <element> <path value="Observation.component"/> <name value="diastolic"/> <!-- mandatory - gives the slice a name --> <min value="1"/> <max value="1"/> </element> <element> <path value="Observation.component.code"/> <min value="1"/> <fixedCodeableConcept> <coding> <system value="http://loinc.org" /> <code value="8462-4" /> <display value="Diastolic blood pressure" /> </coding> </fixedCodeableConcept> </element> <element> <path value="Observation.component.valueQuantity"/> <min value="1"/> </element>
Note: lots of definition detail has been left out, and only the parts relevant to the pattern are shown. E.g. A real blood pressure profile would fix unit, a overall Observation code etc.
For another example, consider slicing extensions. The base extension on every element is defined as a list (0..*) of extensions, and each extension has a url that identifies it, and a value. Consider an example where a profile defines that for a particular element (named Patient), there are two extensions, with URLs http://acme.com/a and http://acme.com/b. In addition, the profile allows other extensions to be used.
Technically, the profile achieves this by "slicing" the extension list, into two slices, and saying that the slicing is "open" - that there can be other slices introduced. Here are the relevant parts of the Profile on patient:
<StructureDefinition xmlns="http://hl7.org/fhir"> <!-- snip --> <constrainedType value="Patient"/> <snapshot> <element> <path value="Patient"/> <!-- snip --> </element> <element> <path value="Patient.extension"/> <!-- this first element defines the slicing, and carries the base definition forward --> <slicing> <discriminator value="url"/> <!-- Extensions are always discriminated by URL --> <ordered value="false"/> <!-- we don't care what order they appear in --> <rules value="open"/> <!-- other extensions can be used --> </slicing> <!-- -- snip definition --> </element> <!-- first extension --> <element> <path value="Patient.extension"/> <!-- snip most of definition --> <type> <code value="Extension"/> <!-- the profile for an extension is a reference to the extension definition itself - this implies a profile, and happens to fix the @url value to the desired URL --> <profile value="http://acme.com/a"/> </type> </element> <!-- second extension --> <element> <path value="Patient.extension"/> <!-- snip most of definition --> <type> <code value="Extension"/> <!-- the profile for an extension is a reference to the extension definition itself - this implies a profile, and happens to fix the @url value to the desired URL --> <profile value="http://acme.com/b"/> </type> </element> <!-- snip rest of profile --> </snapshot> </StructureDefinition>
Here's a patient example that conforms to this profile:
<Patient xmlns="http://hl7.org/fhir"> <!-- two extensions, the order doesn't matter --> <extension url="http://acme.com/b"> <!-- this has the right url, and so matches the second slice --> <!-- snip whatever value extension would have --> </extension> <extension url="http://acme.com/a"> <!-- this has the right url, and so matches the first slice --> <!-- snip whatever value extension would have --> </extension> <!-- the rest of patient --> </Patient>
In this example, a profile on an diagnostic report says that it must have 4 observations, each with a different LOINC code (e.g. a classic lab panel). In this case (taken from the Example Lipid Profile), the structure that applies to DiagnosticReport will say that there are 4 slices on DiagnosticReport.result, each conforming to a different structure, which are also contained in the same profile. Each of those structures will constrain the LOINC code in the observation.
<!-- first structure, the DiagnosticReport --> <StructureDefinition xmlns="http://hl7.org/fhir"> <!-- snip --> <url value="http://acme.org/fhir/StructureDefinition/lipid-report"/> <constrainedType value="DiagnosticReport"/> <base value="http://hl7.org/fhir/StructureDefinition/DiagnosticReport"/> <name value="LipidProfile"/> <!-- snip --> <snapshot> <!-- snip elements --> <element> <!-- first definition for result --> <path value="DiagnosticReport.result"/> <slicing> <!-- this is sliced by the code value of the target of the reference --> <discriminator value="reference.code"/> <!-- have to be in the specified order --> <ordered value="true"/> <!-- this profile says, no other observations allowed --> <rules value="closed"/> </slicing> <!-- snip definition --> </element> <!-- first slice: Cholesterol --> <element> <path value="DiagnosticReport.result"/> <name value="Cholesterol"/> <!-- snip definition parts --> <type> <code value="Reference"/> <!-- this element must conform to the "Cholesterol" structure --> <profile value="http://acme.org/fhir/StructureDefinition/Cholesterol"/> </type> </element> <!-- next 3 slices all the same, but different names for profile --> <element> <path value="DiagnosticReport.result"/> <name value="Triglyceride"/> <!-- snip definition parts --> <type> <code value="Reference"/> <!-- this element must conform to the "Triglyceride" structure --> <profile value="http://acme.org/fhir/StructureDefinition/Triglyceride"/> </type> </element> <element> <path value="DiagnosticReport.result"/> <name value="LDLCholesterol"/> <!-- snip definition parts --> <type> <code value="Reference"/> <!-- this element must conform to the "LDLCholesterol" structure --> <profile value="http://acme.org/fhir/StructureDefinition/LDLCholesterol"/> </type> </element> <element> <path value="DiagnosticReport.result"/> <name value="HDLCholesterol"/> <!-- snip definition parts --> <type> <code value="Reference"/> <!-- this element must conform to the "HDLCholesterol" structure --> <profile value="http://acme.org/fhir/StructureDefinition/HDLCholesterol"/> </type> </element> <!-- snip elements --> </snapshot> </StructureDefinition> <!-- now, the second structure, for the Cholesterol profile --> <StructureDefinition> <url value="http://acme.org/fhir/StructureDefinition/Cholesterol"/> <constrainedType value="Observation"/> <base value="http://hl7.org/fhir/StructureDefinition/Observation"/> <name value="Cholesterol"/> <snapshot> <!-- snip elements --> <element> <!-- this the element definition for name. Because of the slicing / discriminator rules in the LipidReport profile that references it, it is required to fix the value of the name element --> <path value="Observation.code"/> <definition> <!-- there are actually 3 ways to fix a CodeableConcept to a single fixed value. Here, we used the simplest one --> <valueCodeableConcept> <!-- just fix the value to the right code --> <coding> <system value="http://loinc.org"/> <code value="35200-5"/> <display value="Cholesterol"/> </coding> </valueCodeableConcept> </definition> </element> <!-- snip elements --> </snapshot> </StructureDefinition> <!-- Triglyceride profile --> <StructureDefinition> <url value="http://acme.org/fhir/StructureDefinition/Triglyceride"/> <constrainedType value="Observation"/> <base value="http://hl7.org/fhir/StructureDefinition/Observation"/> <name value="Triglyceride"/> <snapshot> <!-- snip elements --> <element> <!-- this the element definition for name. Because of the slicing / discriminator rules in the LipidReport profile that references it, it is required to fix the value of the name element --> <path value="Observation.code"/> <definition> <!-- there's actually 3 ways to fix a CodeableConcept to a single fixed value. Here, we used the simplest one --> <valueCodeableConcept> <!-- just fix the value to the right code --> <coding> <system value="http://loinc.org"/> <code value="35217-9"/> <display value="Triglyceride"/> </coding> </valueCodeableConcept> </definition> </element> <!-- snip elements --> </snapshot> </StructureDefinition> <!-- LDLCholesterol profile --> <StructureDefinition> <url value="http://acme.org/fhir/StructureDefinition/LDLCholesterol"/> <constrainedType value="Observation"/> <base value="http://hl7.org/fhir/StructureDefinition/Observation"/> <name value="LDLCholesterol"/> <snapshot> <!-- snip elements --> <element> <!-- this the element definition for name. Because of the slicing / discriminator rules in the LipidReport profile that references it, it is required to fix the value of the name element --> <path value="Observation.code"/> <definition> <!-- because of the way that LDL cholesterol measurements works (well, in this context- it varies), there's 2 different LOINC codes for either measured or calculated. So here, we bind to a value set --> <binding> <conformance value="required"/> <!-- must be required if this is a discriminator --> <!-- snip the actual value set reference, but it refers to a value set with two LOINC codes, one for each kind of LDL, which in this case are LOINC codes 18262-6 and 13457-7 --> </binding> </definition> </element> <!-- snip elements --> </snapshot> </StructureDefinition> <!-- HDLCholesterol profile --> <StructureDefinition> <url value="http://acme.org/fhir/StructureDefinition/HDLCholesterol"/> <constrainedType value="Observation"/> <base value="http://hl7.org/fhir/StructureDefinition/Observation"/> <name value="HDLCholesterol"/> <snapshot> <!-- snip elements --> <element> <!-- this the element definition for name. Because of the slicing / discriminator rules in the LipidReport profile that references it, it is required to fix the value of the name element --> <path value="Observation.code"/> <definition> <!-- there's actually 3 ways to fix a CodeableConcept to a single fixed value. Here, we used the simplest one --> <valueCodeableConcept> <!-- just fix the value to the right code --> <coding> <system value="http://loinc.org"/> <code value="2085-9"/> <display value="LDL Cholesterol"/> </coding> </valueCodeableConcept> </definition> </element> <!-- snip elements --> </snapshot> </StructureDefinition>
Here is an instance that meets the rules for this profile:
<!-- first, the diagnostic report --> <DiagnosticReport xmlns="http://hl7.org/fhir"> <!-- snip --> <!-- here's the set of results. We don't know what slices they are or anything until we go off, find the references, and look in them --> <result> <reference value="Observation/cholesterol"/> </result> <result> <reference value="Observation/triglyceride"/> </result> <result> <reference value="Observation/ldlcholesterol"/> </result> <result> <reference value="Observation/hdlcholesterol"/> </result> <!-- snip --> </DiagnosticReport> <!-- Observation, id = cholesterol --> <Observation xmlns="http://hl7.org/fhir"> <!-- the observation starts with the name, as specified by the profile for the first slice --> <code> <coding> <system value="http://loinc.org"/> <code value="35200-5"/> <display value="Cholesterol"/> </coding> </code> <!-- snip --> </Observation> <!-- Observation, id = triglyceride --> <!-- this code matches the second slice. good --> <Observation xmlns="http://hl7.org/fhir"> <code> <coding> <system value="http://loinc.org"/> <code value="35217-9"/> <display value="Triglyceride"/> </coding> </code> <!-- snip --> </Observation> <!-- Observation, id = hdlcholesterol --> <!-- this code matches the fourth slice. good --> <Observation xmlns="http://hl7.org/fhir"> <code> <coding> <system value="http://loinc.org"/> <code value="2085-9"/> <display value="HDL Cholesterol"/> </coding> </code> <!-- snip --> </Observation> <!-- Observation, id = ldlcholesterol --> <!-- this code matches the third slice. good --> <Observation id="ldlcholesterol"> <code> <coding> <system value="http://loinc.org"/> <code value="13457-7"/> <display value="LDL Chol. (Calc)"/> </coding> </code> <!-- snip --> </Observation>
Note that this version isn't valid, because the slices are not in the correct order:
<!-- first, the diagnostic report --> <DiagnosticReport xmlns="http://hl7.org/fhir"> <!-- snip --> <!-- here's the set of results. We don't know what slices they are or anything until we go off, find the references, and look in them --> <result> <reference value="Observation/cholesterol"/> </result> <result> <reference value="Observation/triglyceride"/> </result> <result> <reference value="Observation/hdlcholesterol"/> </result> <result> <reference value="Observation/ldlcholesterol"/> </result> <!-- snip --> </DiagnosticReport>
Most uses of Composition involve conformance to a profile that specifies which sections will exist, and what their contents will be. This is yet another example of slicing. A typical document content profile might specify a section structure something like this:
Real profiles will contain lots of detail about the sections, but these are omitted here in the interests of clarity.
An example of a Composition that meets these rules:
<Composition> ... snip ... <section> <code> <coding> <system value="http://loinc.org" /> <use value="29299-5" /> <value value="Reason for visit Narrative" /> </coding> </code> ... snip ... </section> <section> <code> <coding> <system value="http://loinc.org" /> <use value="46057-6" /> <value value="Medications section" /> </coding> </code> ... snip ... <section> <code> <coding> <system value="http://loinc.org" /> <use value="66149-6" /> <value value="Prescribed medications" /> </coding> </code> ... snip ... </section> <section> <code> <coding> <system value="http://loinc.org" /> <use value="66150-4" /> <value value="Over the counter medications" /> </coding> </code> ... snip ... </section> </section> <section> <code> <coding> <system value="http://loinc.org" /> <use value="8716-3" /> <value value="Vital signs" /> </coding> </code> ... snip ... </section> </Composition>
To do this, the profile that implements these rules needs to do the following:
In a StructureDefinition, this will look like:
<!-- setting up the slicing on Composition.section --> <element> <path value="Composition.section"/> <slicing> <discriminator value="code"/> <ordered value="true"/> <rules value="closed"/> </slicing> <!-- net cardinality rules --> <min value="3"/> <max value="3"/> </element> <!-- first slice: reason for visit --> <element> <path value="Composition.section"/> <name value="reason-for-visit"/> <min value="1"/> <max value="1"/> </element> <element> <path value="Composition.section.code"/> <min value="1"/> <fixedCodeableConcept> <coding> <system value="http://loinc.org" /> <use value="29299-5" /> <value value="Reason for visit Narrative" /> </coding> </fixedCodeableConcept> </element> <!-- second slice: medications --> <element> <path value="Composition.section"/> <name value="medications"/> <min value="1"/> <max value="1"/> </element> <element> <path value="Composition.section.code"/> <min value="1"/> <fixedCodeableConcept> <coding> <system value="http://loinc.org" /> <use value="46057-6" /> <value value="Medications section" /> </coding> </fixedCodeableConcept> </element> <!-- setting up the inner slicing on medication Composition.section.section --> <element> <path value="Composition.section.section"/> <slicing> <discriminator value="code"/> <ordered value="true"/> <rules value="closed"/> </slicing> <!-- net cardinality rules --> <min value="1"/> <max value="2"/> </element> <!-- first inner slice: prescribed medications --> <element> <path value="Composition.section.section"/> <name value="prescribed"/> <min value="1"/> <max value="1"/> </element> <element> <path value="Composition.section.section.code"/> <min value="1"/> <fixedCodeableConcept> <coding> <system value="http://loinc.org" /> <use value="66149-6" /> <value value="Prescribed medications" /> </coding> </fixedCodeableConcept> </element> <!-- second inner slice: over the counter medications --> <element> <path value="Composition.section.section"/> <name value="otc"/> <min value="0"/> <max value="1"/> </element> <element> <path value="Composition.section.section.code"/> <min value="1"/> <fixedCodeableConcept> <coding> <system value="http://loinc.org" /> <use value="66150-4" /> <value value="Over the counter medications" /> </coding> </fixedCodeableConcept> </element> <!-- third slice: Vital Signs --> <element> <path value="Composition.section"/> <name value="vital-signs"/> <min value="1"/> <max value="1"/> </element> <element> <path value="Composition.section.code"/> <min value="1"/> <fixedCodeableConcept> <coding> <system value="http://loinc.org" /> <use value="8716-3" /> <value value="Vital signs" /> </coding> </fixedCodeableConcept> </element>