This wiki has undergone a migration to Confluence found Here
<meta name="googlebot" content="noindex">

Difference between revisions of "FHIR Spreadsheet Profile Authoring"

From HL7Wiki
Jump to navigation Jump to search
Line 83: Line 83:
  
 
Most of the columns in the structure definition tab are the same as those used for defining resources.  Details on the meaning of each column can be found here: [[FHIR_Guide_to_Authoring_Resources#Data_Elements_Tab]].  However, there are some additional columns and processes used when profiling structures.  These are documented below.  Finally, there are rules about what sort of changes can be made when profiling resources and data types.  These rules can be found [[FHIR Guide to Designing Resources#What can a profiled structure constrain? | here]]
 
Most of the columns in the structure definition tab are the same as those used for defining resources.  Details on the meaning of each column can be found here: [[FHIR_Guide_to_Authoring_Resources#Data_Elements_Tab]].  However, there are some additional columns and processes used when profiling structures.  These are documented below.  Finally, there are rules about what sort of changes can be made when profiling resources and data types.  These rules can be found [[FHIR Guide to Designing Resources#What can a profiled structure constrain? | here]]
 
====Profile columns====
 
In addition to the normal columns used to define structures, the profiles tab also includes the following:
 
 
* '''Profile name''': This is a unique name within the tab for a particular constrained row.  It only needs to be populated for rows inside of a 'slice' (see below).
 
* '''Must support''': This can be either "Y" or "N".  If blank, "N" is presumed.  A "Y" indicates that systems that claim to conform to the profile structure must "support" the data element - the precise meaning of "support" (for both clients and servers) should be defined by the narrative of the profile.
 
* '''Profile''': This indicates a profile that the specified element must adhere to.  This can only be specified for rows that declare a data type.  I.e. profiles cannot be declared on structures with "complex" types - nested elements.
 
** If multiple types are associated with an element, multiple profiles may also be declared - matching occurs on a 1..1 basis.  For example, if the data types are "Quantity | string | Resource(Patient)", profile could be "#Intensity | | #VeterinaryPatient".
 
** If referencing structures defined within the same profile, the reference should be "#" followed by the structure name.  If referencing structures defined in other profiles, the reference would be the profile URI of the target structure + "#" + the structure name.
 
* '''Discriminator''': This identifies the element path (dot notation) of the element used to disambiguate between sliced rows (see below).  If multiple discriminators are required, they can all be listed with spaces between them. 
 
* '''Value''': This specifies a fixed value for the element.  It may be declared for both simple and complex types.  For complex types, the value should be declared as inline XML.  Note that the expectation is that valid instances will match the specified XML exactly (no extra elements, extensions or properties.)
 
 
Note: When defining resources, two additional tabs - UML and Summary are also available.  These are not presently used for profiles.  We don't have a means of diagramming profiles in UML and profiles aren't permitted to override the Summary characteristic for a resource.
 
  
 
===Referencing "extra" elements===
 
===Referencing "extra" elements===

Revision as of 17:10, 12 October 2014

The FHIR Build process leverages Excel spreadsheets saved in XML format. It should also work using OpenOffice, though this has not been rigorously tested. The process defined below is a short-term (for the next DSTU cycle) process for doing internal HL7 profile development. The process will change after that as more robust implementation guide and profile tooling becomes available later in 2015.

Steps

Decide on resource-specific or "general" profile

Resource-specific profiles are those that profile only one resource or that primarily focuses on a single resource. They will be published in the Resources tab for the resource. "General" resources show up in the list of profiles off the implementer page, but not anywhere else. (As a rule, resource-specific is better because it provides two ways to discover the content.)

Set up resource-specific profile

  1. Copy the template-profile-spreadsheet.xml file from the build/source/templates directory to the same folder as the resource. The name should be "[ResourceName]-[some qualifier]-profile-spreadsheet.xml" where [some qualifier] is a short 1-2 word descriptor that makes the name unique within the folder
  2. In addition, consider copying the template-introduction.xml and template-notes.xml files from the build/source/templates directory if your profile will need to have custom HTML in front of or after the rendering of the profile itself. Most profiles should at least have an introduction. The file-names should be "[ResourceName]-[same qualifier]-['introduction'|'notes'].xml".
  3. Edit the spreadsheet of the *resource* to point to the new profile on the Profiles tab. (If it's an older resource that doesn't have a Profiles tab, or if the Profiles tab doesn't have all of the columns discussed below, you may need to add the tab or update it to align with the content specified in the build/source/templates/template-spreadsheet.xml.) Populate the columns as follows:
    1. Name: The name used to label and reference the profile
    2. Description: Description of the profile shown when it's listed in profileList.html (one sentence or so)
    3. Source: The name of the profile spreadsheet xml file.
    4. Filename: The name of the profile.xml file that should be generated from the spreadsheet. This should generally be ResourceName-[same qualifier].xml
    5. Type: This should always be "spreadsheet" when using the spreadsheet method.

Note: In the future, the Name and Description columns might be removed as they are redundant with information already found in the profile spreadsheet.


Set up "general" profiles

  1. Copy the template-profile-spreadsheet.xml file from the build/source/templates directory to the /build/profiles folder . The name should be "[some qualifier]-spreadsheet.xml" where [some qualifier] is a short 1-2 word descriptor that makes the profile unique within the folder
  2. In addition, consider copying the template-introduction.xml and template-notes.xml files from the build/source/templates directory if your profile will need to have custom HTML in front of or after the rendering of the profile itself. Most profiles should at least have an introduction. The file-names should be "[same qualifier]-['introduction'|'notes'].xml".
  3. Edit the profiles section of the source/fhir.ini file to include a reference in the form [id]=[file], where:
    1. [id] is a unique identifier-like name for the profile
    2. [file] is "profiles/[same-qualifier]-spreadsheet.xml"

Specify Profile Metadata

  1. Open the profile spreadsheet and select the Metadata tab and populate the value column as follows:
    1. id: This is a unique id for the profile within the build environment. Normally human-readable, lower-case, dash-separated. If doing a "general" profile, this is the same as the [id] specified in the fhir.ini file.
    2. name': This is a descriptive name for the profile. If doing a resource-specific profile, this should be the same as the 'Name' for the profile specified in the resource spreadsheet.
    3. name.author: This should be "HL7 International - [owning work group name - e.g. Orders & Observations] WG"
    4. name.reference: This should be the URL for the owning work group on the HL7 website. E.g. http://hl7.org/Special/committees/orders
    5. code: This isn't used at present and should be left blank. If you think you need it, talk to someone from the FMG.
    6. description: If doing a resource-specific profile, this should be the same as the 'Description' for the profile specified in the resource spreadsheet.
    7. status: This should be "draft". It will be changed when the profile goes normative.
    8. date: This should be set to the date the profile was first created. It will be changed when the profile goes normative.
    9. profile: This is the name of the tab that defines one of the structures structure constrained/extended by the profile. It must correspond with the name of one of the tabs in the spreadsheet corresponding to a structure. It must be omitted if the profile only defines extensions and/or search criteria. If a profile defines multiple structures, create multiple rows all with a label of "profile" and specify a distinct structure tab name for each.
    10. version: This should be omitted unless there are specific reasons to declare a business version for the profile
    11. extension.uri: This provides the base URI for extensions and search criteria as well as for structures referenced in other profiles. It also forms the "identifier" for the profile.
    12. introduction: This is the full name of the "notes" HTML file (if one exists). This name must be specified for the introduction to be rendered.
    13. notes: This is the full name of the "notes" HTML file (if one exists). This name must be specified for the notes to be rendered.


Profile Content Options

Within a given profile, you can do any of three things:

  • Define extensions for resource and/or data type elements
  • Define search criteria for a particular resource
  • Define structures (constraints & extensions on a particular resource or data type)

Refer to the [FHIR_Guide_to_Designing_Resources#What should be combined into a single profile? | FHIR Methodology] for guidance on how to determine what should be in a single profile vs. what is best captured in separate profiles.

Define Extensions

Extensions are defined on the Extensions tab. Most columns on the tab are the same as those defined FHIR_Guide_to_Authoring_Resources#Excel_Spreadsheet. Please refer to that link for guidance on populating them. However there are three additional columns:

  • Code: This is the string that must be sent after the extension.uri and the '#' in an instance when identifying this particular extension. E.g. For the extension "http://hl7.org/fhir/Profile/iso-21090#nullFlavor", the "code" would be "nullFlavor". These should generally be lower-camel-case strings. If the extension is part of another extension, the convention is to use string concatenation. E.g. "relationParent.type" as the code for the "type" characteristic of the "relationParent" extension.
  • Context Type: This will be one of 3 values: resource, datatype or extension indicating where the extension is allowed to be used. For "resource", it can be associated with any element in any resource (or any set of elements from one or more resources). The same holds for data types or extensions.
  • Context: This is the list of resource elements, data type elements or extensions this particular extension is allowed to appear in. For resources and data types, this is the full path name of the element. E.g. "Observation.value[x]". For extensions, this is the full path to the corresponding extension this extension is allowed to appear within.

Note: If defining an extension that is part of another extension defined within the same profile, ContextType and Context should be omitted. The naming of the code is sufficient to identify the hierarchical structure. E.g.

code | Context Type | Context | Card. complexExtension | Resource | SomeResource.element | 0..1 complexExtension.node1 | | | 1..1 complexExtension.node2 | | | 0..*


Define Search Criteria

Search criteria for extensions are defined exactly the same way they are for resources. The instructions can be found here: FHIR_Guide_to_Authoring_Resources#Search_Tab. The only special consideration for extension search criteria is that the Path can refer to names outside the profile by prefixing them with the full URL of the profile or resource they're associated with. E.g. To declare a custom search parameter based on Observation.name, you'd use "http://hl7.org/Profile/Observation#Observation.name".

Define structures

Each structure represents the constraints and extensions declared for a particular use of a specified resource or data type. Each structure must be defined on a separate tab and have a unique name within the profile. On each structure tab, the second row of the tab identifies both the resource or data type being profiled as well as the "structure name". The structure name appears in cell A2 (Profile Name). The resource or data type name appears in cell B2 (Element). In addition, if a structure is intended to be based on another profile structure, this can be specified in the same row in the "Profile" column (usually H2).

The structure name should be upper camel case (no spaces and no characters other than alphabetic, numeric or dashes). The format for Profile is the base URL for the profile + "#" + the structure name within the referenced profile. Obviously if creating a profile based on another profile, both must refer to the same resource or data type.

All profiles are authored as "differential" profiles. This means that only those rows and elements that are different from the underlying resource or data element (or specified profile structure on that resource or data element) need to be specified. However, it may be convenient to list all data elements, cardinalities and data types from the underlying resource or profile, just to have a record of what elements are possible. (Note that these should be kept up-to-date if the underlying resource or data type is adjusted). This can be done by copying and pasting the relevant columns from the Resource or Data Type definition spreadsheet.

Most of the columns in the structure definition tab are the same as those used for defining resources. Details on the meaning of each column can be found here: FHIR_Guide_to_Authoring_Resources#Data_Elements_Tab. However, there are some additional columns and processes used when profiling structures. These are documented below. Finally, there are rules about what sort of changes can be made when profiling resources and data types. These rules can be found here

Referencing "extra" elements

When defining a resource, the only elements that appear in the spreadsheet are those that are specific to the resource. If you reference a data type that contains elements, you don't identify the elements that appear inside the data type, only the element that references the data type. In addition, some elements that are implicitly part of a resource (narrative, extension, modifierExtension, etc.) are not mentioned in resource spreadsheets at all. They're automatically assumed to be included at the appropriate position within the resource automatically.

However, when defining profiles on resources and data types, there may be a need to constrain or extend a data element inside a referenced data type or one of the default elements (e.g. requiring that "text" be present within a CodeableConcept or asserting that narrative is 1..1 for a particular resource.

If the set of constraints or extensions on a data type are expected to be common, defining a separate structure and simply referencing it as a profile may be best. However, it is also possible to reference such elements inline. For example, to declare a constraint on the "use" element from the ContactPoint data type within Patient.telecom, the element name would be Patient.telecom.use. Similarly, it would be possible to make a constraint on Patient.narrative, even though that isn't explicitly declared in the defining resource spreadsheet.

Slicing

Slicing is the process by which multiple distinct constraints can be specified on repeating elements. For example, for the repeating Patient.telecom element, you might want to assert that you want 1..5 phone numbers 0..1 fax numbers, 0..2 email addresses and 0..0 web addresses. There are two types of slicing - slicing extensions & modifierExtension; and slicing other elements.

When slicing, it's essential that a given repetition can only correspond to a single slice and that this be verifiable. To accomplish this, when an element needs to be sliced, it's necessary to first declare the "discriminator" or set of discriminators that will allow the repetitions to be disambiguated. A discriminator is a path to an element inside the repeating element that will have a fixed value for each "slice". For example, in the Patient.telecom example above, the discriminator would be "system" because that's the element that would be fixed within each slice (phone/fax/email/url).

For most groups of slices, the discriminator for the group must must be declared on the first slice in the group by specifying the relative path in the "discriminator" tab. Multiple discriminators may be specified by separating each discriminator in the list with a space.

There is one exception to the need to declare a discriminator. When slicing extensions or modifier extensions, the default discriminator is always "url" which does not need to be declared.

In addition, a profile may need to indicate whether order of the slices is important. Finally, a profile can define the "rules" for the slice, indicating whether the set of slices is considered to be complete (closed) or whether additional repetitions that don't meet any of the slice patterns are also permitted, and if so, whether those additional repetitions may appear anywhere (open), or whether they must appear after the declared slices (openAtEnd). The profile might also declare whether slices in an instance must appear in the order specified.

Using the spreadsheet mechanism, the slicing path, ordered nature and rules are all specified in a single column, separated by "|".

Finally, each "slice" must have a unique name. This name appears in the specification and allows referencing the constraints associated with a particular slice. (It also allows slicing slices in subsequent profiles.) This name is specified in the Profile Name column. It can be any string, though is generally limited to only one or two words.