Stream: conformance
Topic: Slicing by target profile of a reference?
Simone Heckmann (Aug 09 2017 at 11:16):
Is it possible to slice by target profile of a reference, and if so: what's the discriminator?
Simone Heckmann (Aug 09 2017 at 11:17):
I would have guesses "Type:Profile Path:reference" but that doesn't seem to work
Michel Rutten (Aug 09 2017 at 13:22):
Great question...!
The spec may provide some clues:
https://www.hl7.org/fhir/profiling.html#discriminator
I think discriminator type "profile" is specifically intended to match type.profile and not type.targetProfile. Maybe you could leverage the special .resolve() fhir path expression that is specifically allowed in this context?
Michel Rutten (Aug 09 2017 at 13:32):
Looks like the LipidProfile example tries to slice DiagnosticReport.result on target profile:
http://hl7.org/fhir/lipidprofile.profile.xml.html
<discriminator> <type value="value"/> <path value="reference.code"/> </discriminator>
However I'm not sure if this is actually correct, as the documentation on discriminators suggests the use of the resolve() operator...?
Michel Rutten (Aug 09 2017 at 13:35):
The official documentation suggests the following syntax:
Context: List.entry
Discriminator type: profile
Discriminator path: item.reference.resolve()
"Entries are differentiated by a profile tag on the target of the reference, as specified by a structure definition"
Michel Rutten (Aug 09 2017 at 13:36):
@Grahame Grieve & @Lloyd McKenzie any suggestions?
Lloyd McKenzie (Aug 09 2017 at 20:32):
I'll defer to @Grahame Grieve on this one.
Grahame Grieve (Aug 10 2017 at 04:51):
well, the lipid thing looks wrong, though the validator works on it. weird.
Grahame Grieve (Aug 10 2017 at 04:52):
the official documentation Michel quoted is what I think is correct
Rob Hausam (Nov 30 2018 at 09:45):
@Grahame Grieve @Lloyd McKenzie @Michel Rutten I'm re-engaging this topic as we have the same question now for the IPS IG and haven't yet found a working FHIRPath expression for the discriminator path. The documentation on this has changed for R4, as 'reference' has been removed and for the List.entry example the discriminator path is now item.resolve()
. We're slicing on the Composition.section.entry reference of an already sliced section (for example Composition.section:sectionMedications.entry). Composition.section.entry is modeled differently from List.entry which is used in the documentation, as Composition.section:sectionMedications.entry itself is of type Reference rather than the additional List.entry.item element. An example of what we have right now (we've tried various permutations) is:
<element id="Composition.section:sectionMedications.entry"> <path value="Composition.section.entry"/> <slicing> <discriminator> <type value="profile"/> <path value="resolve()"/> </discriminator> <rules value="openAtEnd"/> </slicing> <min value="1"/> <mustSupport value="true"/> </element> <element id="Composition.section:sectionMedications.entry:medicationStatement"> <path value="Composition.section.entry"/> <sliceName value="medicationStatement"/> <min value="1"/> <type> <code value="Reference"/> <targetProfile value="http://hl7.org/fhir/uv/ips/StructureDefinition/MedicationStatement-uv-ips"/> </type> <mustSupport value="true"/> </element> <element id="Composition.section:sectionMedications.entry:medicationStatement.reference"> <path value="Composition.section.entry.reference"/> <min value="1"/> <mustSupport value="true"/> </element>
And when parsing an IPS bundle example the QA shows this error:
Bundle/IPS-examples-Bundle-01: Bundle.entry[5].resource.code.coding error Unable to resolve discriminator
Most likely we're doing something wrong, so any suggestions as to what the correct FHIRPath syntax should be for this would be most welcome.
Rob Hausam (Nov 30 2018 at 09:52):
I've looked into where the 'Unable to resolve discriminator' exception is thrown in FHIRPathEngine, but so far that hasn't really shed any light on the issue.
Michel Rutten (Nov 30 2018 at 09:55):
Hi @Rob Hausam, hard to say... the snapshot generator and validator in the FHIR .NET API haven't been updated to R4 yet, so we can't actually test your example. However @Ewout Kramer recently mentioned that he had implemented support for profile-based discriminators. Ewout, can you provide some clarification?
Rob Hausam (Nov 30 2018 at 14:57):
I think this issue was different than we originally thought and the error messages are now resolved. But if anyone is able to confirm that the syntax we are using is correct (or not), that would be great.
Rob Hausam (Dec 02 2018 at 15:15):
I believe that the resolve()
syntax for the path expression is correct, as that fixes the 'Unable to resolve discriminator' error. But, unfortunately, it results in a new type of error when evaluating the example bundle:
Problem evaluating slicing expression for element in profile http://hl7.org/fhir/uv/ips/StructureDefinition/Composition-uv-ips path Bundle.entry[1].resource.section[1].entry (fhirPath = true and resolve().conformsTo('http://hl7.org/fhir/uv/ips/StructureDefinition/Condition-uv-ips')): null
The reference to the Condition-uv-ips profle is the correct one, but it doesn't recognize the identified resource in the bundle as being one of those, even though the resource instance in the bundle has the meta profile tag:
<meta> <profile value="http://hl7.org/fhir/uv/ips/StructureDefinition/Condition-uv-ips"/> </meta>
Not sure at this point where to look next to fix this, so any suggestions are very welcome.
Rob Hausam (Dec 02 2018 at 15:16):
@Grahame Grieve @Lloyd McKenzie @Ewout Kramer @Michel Rutten?
Ewout Kramer (Dec 03 2018 at 10:41):
Hi @Rob Hausam, hard to say... the snapshot generator and validator in the FHIR .NET API haven't been updated to R4 yet, so we can't actually test your example. However @Ewout Kramer recently mentioned that he had implemented support for profile-based discriminators. Ewout, can you provide some clarification?
Since I have not implemented this at all yet, these errors must come from the Java IG/validator ;-)
Syntax-wise, the single "resolve()" looks ok, since that is in line with the List.entry example here (http://build.fhir.org/profiling.html#discriminator).
Richard Ettema (Dec 03 2018 at 13:56):
@Rob Hausam
Bundle/IPS-examples-Bundle-01: Bundle.entry[5].resource.code.coding error Unable to resolve discriminator
This error from the ValidationEngine is pointing to the 5th Bundle entry of the IPS-examples-Bundle-01 example resource which is a Condition. The specific path points to the Condition.code.coding element. The "Unable to resolve discriminator" message is being thrown because the IPS Condition Profile's slicing definition on the Condition.code.coding element does not contain a discriminator.path.
Here's the differential definition of the IPS Condition Profile Condition.code.coding element:
<element id="Condition.code.coding"> <path value="Condition.code.coding"/> <slicing> <description value="Discriminated by value set biding"/> <rules value="open"/> </slicing> <definition value="Identification of the condition, problem or diagnosis or recording of "problem absent" or of "problems unknown"."/> <min value="1"/> <mustSupport value="true"/> </element>
As you can see, the slicing element does not contain a discriminator. So, the FHIRPathEngine does not have a path to evaluate.
Rob Hausam (Dec 04 2018 at 03:12):
@Richard Ettema Yes, that's what I was referring to (but not explicitly) when I said "I think this issue was different than we originally thought and the error messages are now resolved". We had the "Unable to resolve discriminator" error when the discriminator path was there, and removing the discriminator path (and therefore the entire discriminator including the type since path is required) is what we did to resolve the errors. And I think that makes sense, as the discriminator isn't always required and in this case as long as the value sets that are bound for each slice are not overlapping (as is supposed to be the case) then when they are evaluated the validator can determine the correct slice.
Lloyd McKenzie (Dec 10 2018 at 22:13):
If you remove the discriminator, then you're not slicing anymore (or if you are, you're declaring new slices based on the discriminator of the parent...)
Rob Hausam (Dec 10 2018 at 22:35):
@Lloyd McKenzie Not sure about that. It's obviously not recommended, but this statement on the profiling.html page clearly indicates that it is allowed: "A structure definition is not required to designate any discriminator at all for a slice, but those that don't identify discriminators are describing content that is very difficult to process, and so this is discouraged." With that said, though, I think we do need a discriminator - but it needs to be one that actually works when validating instance data. So far I haven't been able to discover what that is exactly. If you are now back and have some availability, I would like to find some time to go over with you the details of the slicing and discriminators and the issues that we are having, and either see what we need to do differently for it to work correctly, see what might need still to be fixed in the spec or tooling, or see what we think Grahame may need to agree to pass as an acceptable error or warning.
Lloyd McKenzie (Dec 10 2018 at 22:45):
If you're just declaring slicing with a description, you can, but that means there's no computable behavior happening with validators or anything else that doesn't write custom code based on what you put in slicing.description.
Lloyd McKenzie (Dec 10 2018 at 22:48):
The validator doesn't currently support slicing by profile of a target reference. Doing so is quite processing intensive. The general recommendation is to instead slice by something that's distinct for each profile (e.g. a fixed code or something). One thing you can do is have your profiles mandate that they're declared in meta.profile and then slice by value looking at that.
Rob Hausam (Dec 10 2018 at 22:51):
Agree. We do want the discriminator. We ended up removing it because that wasn't "wrong" and was the only way that we found to resolve some errors. But I want to put it back and have it work.
Richard Townley-O'Neill (Jan 22 2019 at 05:42):
@Rob Hausam any progress?
Richard Townley-O'Neill (Jan 22 2019 at 05:51):
We have similar problems. When slicing by profile:resolve() the ig publisher give the error
Problem evaluating slicing expression for element in profile http://ns.electronichealth.net.au/ci/fhir/3.0/StructureDefinition/composition-phs-1 path Composition.section[1].entry (fhirPath = true and resolve().conformsTo('http://ns.electronichealth.net.au/ci/fhir/3.0/StructureDefinition/allergyintolerance-summary-1')): null
If I have an example that tries to meet the profile.
We are using STU3
Rob Hausam (Jan 22 2019 at 06:03):
@Richard Townley-O'Neill I didn't get back to this over the holidays or leading up to the WGM and we didn't manage to get to it in our evening session on IGs or another time during the week last week in San Antonio. But we need to get it resolved for IPS (using R4). I think I'll start with @Lloyd McKenzie's suggestion to mandate that the instance declares meta.profile and try to slice by value on that via the reference and see if that proves to be a sufficiently workable approach. Not as powerful, but it seems as if it should work. @Grahame Grieve also will be working on IGs and will need time from him if there are still issues.
Richard Townley-O'Neill (Jan 22 2019 at 06:09):
Our profiles are mandating meta.profile:
<constraint> <key value="inv-dh-cmp-01"/> <severity value="error"/> <human value="One meta.profile shall be http://ns.electronichealth.net.au/ci/fhir/3.0/StructureDefinition/composition-phs-1"/> <expression value="meta.profile.where($this='http://ns.electronichealth.net.au/ci/fhir/3.0/StructureDefinition/composition-phs-1').exists()"/> </constraint>
Richard Townley-O'Neill (Jan 22 2019 at 06:11):
Oh!. Just reread Lloyd's suggestion. I'll give that a go.
Rob Hausam (Feb 04 2019 at 12:34):
@Lloyd McKenzie @Grahame Grieve @Richard Townley-O'Neill @Michel Rutten Does anyone have example(s) of the correct syntax for doing this with resolve()? I'm trying to slice on the fixed canonical value of meta.profile across the reference. I think I'm getting close, but I haven't figured out the correct syntax that works yet.
Rob Hausam (Feb 04 2019 at 12:35):
The documentation seems rather sparse on this.
Grahame Grieve (Feb 04 2019 at 12:41):
I'll have a chance to look at this on Wednesday my time
Rob Hausam (Feb 04 2019 at 12:42):
great
Rob Hausam (Feb 06 2019 at 21:23):
@Grahame Grieve Did you have a chance to take a look at this? I'll keep doing some work on it further in the meantime.
Grahame Grieve (Feb 07 2019 at 00:02):
do you want to add a test case for this, and we'll iterate on it
Rob Hausam (Feb 07 2019 at 00:13):
ok - will do that
Michel Rutten (Feb 11 2019 at 11:03):
I @Rob Hausam, I can't find a concrete example of such an expression. You may be able to get some inspiration from a profile created by colleague @Vadim: https://simplifier.net/temporary-swedish-pa/mymedicationrequest
Specifically, look at the expression for constraint "medication-1" on the root element. This expression uses resolve() to inspect another (sibling) element.
Chris Grenz (Mar 12 2019 at 09:43):
I'd expect NOT to use resolve when profiling across a reference and instead to rely on the targetProfile element of type. However, that seems to be at odds with the valueset comments. Here's an example:
{ "differential": { "element": [ { "id":"Encounter.participant", "path": "Encounter.participant", "slicing": { "discriminator": [{ "type": "profile", "path": "individual.reference" }], "rules": "open" } }, { "id": "Encounter.participant:withParticularID", "path": "Encounter.participant", "sliceName": "withParticularID" }, { "id": "Encounter.participant:withParticularID.individual.reference", "path": "Encounter.participant.individual.reference", "type": [{ "code": "string", "targetProfile": "http://example.com/fhir/StructureDefinition/practitioner-with-particular-id" }] } ] } }
Chris Grenz (Mar 12 2019 at 09:46):
http://hl7.org/fhir/STU3/valueset-discriminator-type.html in STU3 is silent on the matter. R4 clarified (badly IMO): http://hl7.org/fhir/valueset-discriminator-type.html that resolve() was to be used. This requires the validator to match a .resolve() path with type.targetProfile
(backtracking) and a non resolve() path with type.profile
.
Chris Grenz (Mar 12 2019 at 09:47):
This leaves the question of when both profile and targetProfile are set (which is legal as far as I can tell...)? Is one to be treated as discriminator and the other as validation?
Rob Hausam (Mar 12 2019 at 13:09):
Thanks, @Chris Grenz In IPS we still have these questions, and would like to get this "resolved". :)
Grahame Grieve (Mar 14 2019 at 07:27):
I don't know the answer to this
Chris Grenz (Mar 26 2019 at 09:22):
WGM topic?
Chris Grenz (Mar 26 2019 at 09:24):
@Rob Hausam - maybe open a clarification tracker that can be triaged to WGM in person.
Rob Hausam (Mar 29 2019 at 22:10):
@Chris Grenz good suggestion - I'll probably do that on the plane home from Finland on Sunday (or maybe tomorrow, but don't think I will get to it tonight after a good but intense week)
Patrick Werner (Aug 12 2019 at 21:13):
do we now know the answer to this? I have a also a related question: if i slice on the resource/target profile. Which counts: meta statement about the profile in the target, or if the entry validates against one of the slices, what happens if it validates against 2 slices?
Michel Rutten (Aug 13 2019 at 08:34):
Hi @Patrick Werner, interesting question. Ewout explains that the .NET Validator probably performs a "greedy" match, i.e. map to the first slice entry with a matching targetProfile and ignore any others. An advanced validator implementation could try to match against all specified targetProfiles and report ambiguous matches. However this would be quite cpu-intensive, hence the current "greedy" approach.
Lloyd McKenzie (Aug 19 2019 at 01:56):
I think the Java reference implementation currently tries to match everything and hollers if it finds more than one (or none). Profiles certainly shouldn't rely on a greedy match approach (i.e. all target profiles need to be mutually exclusive)
Last updated: Apr 12 2022 at 19:14 UTC