Stream: shorthand
Topic: Exclude inherited array elements
Joe Paquette (Mar 02 2021 at 15:52):
Background:
I am defining a Patient profile in FSH having the parent = USCorePatientProfile. I'm defining a slice on the identifier
attribute. The slice is working just fine.
The parent identifier
defines an example for identifier.value
in its array of examples. Within the slice definition, I want to replace the parent's example
array element with my slice-specific example
. In my slice definition, I have:
* identifier[mrn].value ^example[0].label = "My example Label"
* identifier[mrn].value ^example[0].valueString = "My example content"
This successfully adds my example to the array of examples, but the parent's example
element still exists. From the identifier slice element:
"example" : [
{
"label" : "General",
"valueString" : "123456"
},
{
"label" : "My example Label",
"valueString" : "My example content"
}
],
Question:
Within the FSH definition, how can I "remove" the unwanted inherited example?
In fact, how can I "removed" any inherited non-array ElementDefinition attributes such as comment
, requirements
, etc. I could override them with my own content, but in some cases, I just don't need or want some of those elements.
Chris Moesel (Mar 02 2021 at 23:02):
That is an excellent question, @Joe Paquette. I've reproduced the situation locally in order to ensure I understand it. From what I can see, SUSHI properly creates the sliced identifier
and the differential contains only the example
you provided in the FSH. So that is good.
But... when the IG Publisher builds the snapshot for the slice, it "inherits" the US Core example
from the base identifier
element and appends your example
(from the mrn
slice element in the differential) to it. So, the IG Publisher interprets an example
array in a slice as being additive to the example array in the base (sliced) element.
I think this actually leads to three relevant questions:
-
Is it proper and expected behavior for the IG Publisher to copy examples from a sliced element to each of its slices? I would propose that it is not proper because there is no guarantee that an example in a sliced element conforms to every defined slice of it. @Grahame Grieve? @Lloyd McKenzie? Would you agree?
-
Is there a way in
StructureDefinition.differential.element
to say "delete this property"? Omission of a property in a differential element indicates "no change" (i.e., keep the property the same). Can you simply set it tonull
to effectively delete it from the snapshot (e.g."example": null
)? Is that the proper approach? -
Is there a way in FHIR Shorthand to delete a property (i.e., the corresponding FSH for whatever the solution is in 2 above)? Currently there is not, but it actually depends on the answer to # 2 above.
Lloyd McKenzie (Mar 02 2021 at 23:47):
- It is proper. In the snapshot for a slice, it inherits everything from the slicing base, plus changes from the slice differential. (And the slicing base inherits from the ancestor models.) It might be noisy, but it's correct.
- There isn't right now, but we could possibly look at a new extension we could put in a differential that allows the removal of certain things. We'd need to limit it those that are truly safe to remove. Comments, aliases, mappings, rationale, examples are fair game. Something like description or binding would not be (though maybe we could do that for example and preferred bindings?)
- FSH could certainly come up with a light-weight way of invoking the extension if we define one.
Next step would be for someone to write up a change proposal to define the extension I guess and then FHIR-I can take it up. We'd have to evaluate whether that's a kosher thing from a backward compability/normative perspective, but given that the elements we'd be looking at suppressing are not things that would impact validation or meaning, I think its ok.
Chris Moesel (Mar 03 2021 at 15:43):
Thanks, @Lloyd McKenzie. Regarding #1 (properness) -- there is still some gray area as it pertains to arrays in differentials. Sometimes an array in a differential is meant to fully replace the original array in the snapshot (as in ElementDefinition.type
), but sometimes it is meant to be additive (as in ElementDefinition.constraint
). So it seems to me it is fair to question how the example
array should operate -- should it be a replacement or an appendix?
Even if the spec is clear that differential example
entries should be appended to the inherited array, I guess I question if that is the right thing to do. For example, does it make sense for a slice element representing a MRN (with a specific system) to have an example of a SSN (with a different system) -- just because the slicing base had that example? I don't think so. In my opinion, having a SSN example on a MRN element violates the definition of example
:
A sample value for this element demonstrating the type of information that would typically be found in the element.
So, I guess I'm changing my question from "is it proper?" (for which the answer is apparently "yes") to "should it be proper?" (which I would suggest the answer is "no"). I think we need to do a better job defining the rules for how differentials work anyway (per a different thread) -- so do you think this is something that could be clarified to work in a more semantically correct way?
Lloyd McKenzie (Mar 03 2021 at 16:10):
ElementDefinition.constraint is a sparse override. If you were to specify the same constraint key, then it would replace the parent. If you specify something with a new key, it would add. Constraints can't ever be removed, so "replace" for the whole collection is nonsensical. On the other hand, examples and aliases can absolutely be removed, so replacement makes sense. I accept that documentation should be clearer around expected behavior of each element in differential. It sounds like we need to do two things:
- are differential values replacements, supplements, or 'matched' updates + supplements?
- when doing 'matched' updates, are the updates 'sparse' (only include child elements that change + the key) or 'complete' (any child elements not included in the 'update' differential element are considered removed)
Care to submit a change request?
Chris Moesel (Mar 03 2021 at 17:12):
Sure thing. Thanks, Lloyd!
Joe Paquette (Mar 03 2021 at 22:00):
@Chris Moesel @Lloyd McKenzie Thanks! Very educational for me! I agree completely that the list of "removal" candidates in a slice is small. From my perspective, the following ElementDefinition attributes are likely candidates:
- comment
- requirements
- alias
- example
There could/might be others, but I leave that to those who know a lot more than I do!
Thanks again!
Chris Moesel (Mar 03 2021 at 22:28):
OK. I have created two change requests to cover these topics.
Chris Moesel (Mar 03 2021 at 22:29):
@Firely Bot issue show FHIR-31405
Firely Bot (Mar 03 2021 at 22:29):
FHIR-31405 Clarify expected behavior of ElementDefinition properties in differential
Status: Submitted, Type: Change Request
Chris Moesel (Mar 03 2021 at 22:30):
@Firely Bot issue show FHIR-31406
Firely Bot (Mar 03 2021 at 22:30):
FHIR-31406 Support "deleting" unwanted inherited properties in profiles
Status: Submitted, Type: Change Request
Last updated: Apr 12 2022 at 19:14 UTC