This page is part of the FHIR Specification (v0.5.0: DSTU 2 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 R3 R2
As an 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) 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's the relevant parts of the Profile on patient:
<Profile xmlns="http://hl7.org/fhir"> <!-- snip --> <structure> <!-- snip --> <type 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"/> <definition> <!-- 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> </definition> </element> <!-- first extension --> <element> <path value="Patient.extension"/> <definition> <!-- 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> </definition> </element> <!-- snip rest of profile --> </snapshot> </structure> </Profile>
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 is 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.
<Profile xmlns="http://hl7.org/fhir"> <!-- snip --> <structure> <!-- first structure, the DiagnosticReport --> <type 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 name value of the target of the reference --> <discriminator value="reference.name"/> <!-- 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 is just for documentation purposes - not used any other way --> <name value="Cholesterol"/> <definition> <!-- snip definition parts --> <type> <code value="Reference"/> <!-- this element must conform to the "Cholesterol" structure --> <profile value="#Cholesterol"/> </type> </definition> </element> <!-- next 3 slices all the same, but different names for profile --> <element> <path value="DiagnosticReport.result"/> <!-- name is just for documentation purposes - not used any other way --> <name value="Triglyceride"/> <definition> <!-- snip definition parts --> <type> <code value="Reference"/> <!-- this element must conform to the "Cholesterol" structure --> <profile value="#Triglyceride"/> </type> </definition> </element> <element> <path value="DiagnosticReport.result"/> <!-- name is just for documentation purposes - not used any other way --> <name value="LDLCholesterol"/> <definition> <!-- snip definition parts --> <type> <code value="Reference"/> <!-- this element must conform to the "Cholesterol" structure --> <profile value="#LDLCholesterol"/> </type> </definition> </element> <element> <path value="DiagnosticReport.result"/> <!-- name is just for documentation purposes - not used any other way --> <name value="HDLCholesterol"/> <definition> <!-- snip definition parts --> <type> <code value="Reference"/> <!-- this element must conform to the "Cholesterol" structure --> <profile value="#HDLCholesterol"/> </type> </definition> </element> <!-- snip elements --> </snapshot> </structure> <!-- now, the second structure, for the Cholesterol profile --> <structure> <type value="Observation"/> <base value="http://hl7.org/fhir/StructureDefinition/Observation"/> <name value="Cholesterol"/> <!-- this is the target of #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.name"/> <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="35200-5"/> <display value="Cholesterol"/> </coding> </valueCodeableConcept> </definition> </element> <!-- snip elements --> </snapshot> </structure> <!-- Triglyceride profile --> <structure> <type value="Observation"/> <base value="http://hl7.org/fhir/StructureDefinition/Observation"/> <name value="Triglyceride"/> <!-- this is the target of #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.name"/> <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> </structure> <!-- LDLCholesterol profile --> <structure> <type value="Observation"/> <base value="http://hl7.org/fhir/StructureDefinition/Observation"/> <name value="LDLCholesterol"/> <!-- this is the target of #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.name"/> <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> <name value="LDL Cholesterol codes"/> <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> </structure> <!-- HDLCholesterol profile --> <structure> <type value="Observation"/> <base value="http://hl7.org/fhir/StructureDefinition/Observation"/> <name value="HDLCholesterol"/> <!-- this is the target of #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.name"/> <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> </structure> </Profile>
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 --> <name> <coding> <system value="http://loinc.org"/> <code value="35200-5"/> <display value="Cholesterol"/> </coding> </name> <!-- snip --> </Observation> <!-- Observation, id = triglyceride --> <!-- this code matches the second slice. good --> <Observation xmlns="http://hl7.org/fhir"> <name> <coding> <system value="http://loinc.org"/> <code value="35217-9"/> <display value="Triglyceride"/> </coding> </name> <!-- snip --> </Observation> <!-- Observation, id = hdlcholesterol --> <!-- this code matches the fourth slice. good --> <Observation xmlns="http://hl7.org/fhir"> <name> <coding> <system value="http://loinc.org"/> <code value="2085-9"/> <display value="HDL Cholesterol"/> </coding> </name> <!-- snip --> </Observation> <!-- Observation, id = ldlcholesterol --> <!-- this code matches the third slice. good --> <Observation id="ldlcholesterol"> <name> <coding> <system value="http://loinc.org"/> <code value="13457-7"/> <display value="LDL Chol. (Calc)"/> </coding> </name> <!-- 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>