FHIR Chat · Handling choice elements · fhirpath

Stream: fhirpath

Topic: Handling choice elements


view this post on Zulip Ewout Kramer (Jul 14 2021 at 09:30):

We recently discovered a bug in our .NET implementation where some parts of our infrastructure accept Condition.onsetPeriod = .... where other parts don't. The spec is very clear about this (https://hl7.org/fhir/fhirpath.html#polymorphism): it should be Condition.onset. While we were planning to fix this, we noticed the Java implementation also accepts Condition.onsetPeriod, so now we are torn: stick to the normative spec (and become incompatible with the Java implementation and thus quite some FP statements in the wild) or submit a tracker item to document this in the FP spec (or FHIR appendix) to allow this as some kind of backwards compat behaviour?

view this post on Zulip Lloyd McKenzie (Jul 14 2021 at 13:53):

@Grahame Grieve

view this post on Zulip Brian Postlethwaite (Jul 14 2021 at 20:19):

And would also be interested in the results from the fhirpathjs implementation too

view this post on Zulip Brian Postlethwaite (Jul 14 2021 at 20:20):

(and Grahame's Delphi version)

view this post on Zulip Paul Lynch (Jul 27 2021 at 16:01):

Brian Postlethwaite said:

And would also be interested in the results from the fhirpathjs implementation too

fhirpath.js would accept onsetPeriod or just onset. There are some cases when fhirpath.js cannot figure out that the field is a choice type, in which case only the name with the type would work.

I have never seen the advantage of removing the type from the field name (though I concede that is per spec).

view this post on Zulip Ewout Kramer (Jul 28 2021 at 06:39):

I have never seen the advantage of removing the type from the field name (though I concede that is per spec).

Because the name of the element in the datamodel (and thus for many, the property name of classes in generated code in C#, Java, Delphi...) is different than the specific serialization of such FHIR choice elements in json and xml. If FhirPath was going to be used for FHIR only, we could argue they are practically the same, but FhirPath can be (and is) used for other models too, where there is no such mapping to a serialization. Hence it made more sense to us to keep this "clean" (early version of FhirPath did use the suffixed names, before we had ofType()).

view this post on Zulip Grahame Grieve (Aug 17 2021 at 04:43):

@Ewout Kramer condition.onsetPeriod should not be supported. That's a bug and surely there's a test case for that?

view this post on Zulip Ewout Kramer (Aug 18 2021 at 08:27):

You would think so... What we'll do is that we will fix our engine to be completely strict here, and when we are fixing that bug, we'll make sure there is a testcase for it in the suite.

view this post on Zulip Lee Surprenant (Aug 19 2021 at 18:43):

Late to this party, but I recently noticed that the spec has a few search parameter expression that get this wrong as well.
image.png

Will open a jira ticket to request those to be instantiates as Canonical and instantiates as Uri.

view this post on Zulip Lee Surprenant (Aug 19 2021 at 18:54):

FHIR#33214

view this post on Zulip Grahame Grieve (Aug 19 2021 at 20:11):

those are separate elements in CarePlan

view this post on Zulip Lee Surprenant (Aug 25 2021 at 02:02):

wow, you are totally right. i'm not sure why I was thinking this was a choice type. i will retract that tracker

view this post on Zulip Ewout Kramer (Aug 25 2021 at 07:00):

Related, this is particularly nasty: http://hl7.org/fhir/2021May/ingredient.html

There is both concentration[x] and concentrationHighLimit[x] - I wonder how many "naive" implementations for parsers this will break....

view this post on Zulip Grahame Grieve (Aug 25 2021 at 07:01):

I'm surprised that's OK with the tools. i don't think it's OK and it won't make R5

view this post on Zulip Lee Surprenant (Aug 25 2021 at 14:51):

just had a quick peak and R4B has concentration[x] and concentrationText... is that one ok?

view this post on Zulip Ewout Kramer (Aug 25 2021 at 16:18):

In R4B Ingredient, I see "concentration", but not "concentration[x]", so these 3 elements starting with "concentration" should be OK.

view this post on Zulip Lee Surprenant (Aug 25 2021 at 19:29):

am I in the wrong spot? https://build.fhir.org/branches/R4B/ingredient.html

image.png

view this post on Zulip Chris Moesel (Aug 25 2021 at 20:03):

I suspect that @Ewout Kramer was looking at the official R4B ballot: http://hl7.org/fhir/2021Mar/ingredient.html

Ingredient-FHIR-v4.1.0-20210825160217.png

view this post on Zulip Chris Moesel (Aug 25 2021 at 20:08):

Looks like there was a ballot comment complaining about the separate low/high properties and the resolution was to add a choice between Range and RatioRange -- resulting in the current build that @Lee Surprenant noticed. (JIRA issue w/ resolution to add the choice: https://jira.hl7.org/browse/FHIR-31821).

view this post on Zulip Grahame Grieve (Aug 26 2021 at 02:37):

clearly, the name detection clash is failing. @Rik Smithies this is a big deal; the names must be different, and I'll have to figure out why, but please start changing them now.

view this post on Zulip Grahame Grieve (Aug 26 2021 at 02:38):

you cannot have an element name nnn[x] and then any other element that starts with nnn

view this post on Zulip Maximilian Reith (Aug 26 2021 at 07:46):

Grahame Grieve said:

Ewout Kramer condition.onsetPeriod should not be supported. That's a bug and surely there's a test case for that?

Ewout Kramer said:

You would think so... What we'll do is that we will fix our engine to be completely strict here, and when we are fixing that bug, we'll make sure there is a testcase for it in the suite.

Which effects could i expect in hl7-Validator and Simplifier-Validator at existing constraints with e.g. condition.onsetPeriod in it? The constraints won't fire or will always fire?

view this post on Zulip Grahame Grieve (Aug 26 2021 at 07:57):

It depends on how you write them. onsertPeriod will be null, and that will propagate according to the rules here http://hl7.org/fhirpath/N1/#null-and-empty. A constraint that returns null is a constraint that is not known to be true, and so is considered to have failed

view this post on Zulip Grahame Grieve (Aug 26 2021 at 21:30):

I got around to looking at the tests, and I don't think that this can be true:

While we were planning to fix this, we noticed the Java implementation also accepts Condition.onsetPeriod

view this post on Zulip Grahame Grieve (Aug 26 2021 at 21:30):

because there is a test case for that

view this post on Zulip Grahame Grieve (Aug 26 2021 at 21:30):

 <group name="polymorphics">
    <!--
      The way FHIRpath works, it treats polymorphic values e.g. Observation.value[x] as
      Observation.value. This catches people out - they often write Observation.valueString.

      For this reason, some engines have a non-strict mode where this is allowed, but it's not
      technical conformant. While this might change in the future, it's not legal in strict mode.
      these tests test this out.
    -->
        <test name="testPolymorphicsA" inputfile="observation-example.xml"><expression>Observation.value.exists()</expression><output type="boolean">true</output></test>
        <test name="testPolymorphicsB" inputfile="observation-example.xml"><expression invalid="semantic">Observation.valueQuantity.exists()</expression><output type="boolean">false</output></test>
        <modeTest mode="lenient/polymorphics" name="testPolymorphicsC" inputfile="observation-example.xml"><expression>Observation.valueQuantity.exists()</expression><output type="boolean">true</output></modeTest>
        <modeTest mode="lenient/polymorphics" name="testPolymorphicsD" inputfile="observation-example.xml"><expression>Observation.valueString.exists()</expression><output type="boolean">false</output></modeTest>
  </group>

view this post on Zulip Grahame Grieve (Aug 26 2021 at 21:31):

the java FHIRPath implementation acccepts onsetPeriod only if set to lenient mode, and this is only set for the second pair of tests here.

view this post on Zulip Grahame Grieve (Aug 26 2021 at 21:31):

So I don't think that the java implementation should accept onsetPeriod @Ewout Kramer

view this post on Zulip Ewout Kramer (Aug 27 2021 at 09:34):

Ah - that's good news. I know we accepted in one of the very first drafts of FhirPath, but that must be years ago.

view this post on Zulip Maximilian Reith (Aug 31 2021 at 07:09):

Grahame Grieve said:

It depends on how you write them. onsertPeriod will be null, and that will propagate according to the rules here http://hl7.org/fhirpath/N1/#null-and-empty. A constraint that returns null is a constraint that is not known to be true, and so is considered to have failed

Hmm that's bad for IGs which have relied on the output of the validator. There are a lot of profils which can not be changed in a short time and that change immediately will make them faulty . What about a transition phase in which both approaches will work?

view this post on Zulip Grahame Grieve (Aug 31 2021 at 07:11):

what's an example?

view this post on Zulip Maximilian Reith (Aug 31 2021 at 07:18):

I will ask them if i could use there example...guess i can reply today

view this post on Zulip Maximilian Reith (Aug 31 2021 at 12:09):

Grahame Grieve said:

what's an example?

okay we have serveral interfaces in which this problem takes place. All of these interfaces are wide spread and cannot be updated shortly.

e.g. An interface for a certificate of incapacity for work
https://simplifier.net/eau/kbvpreaubundle

      <constraint>
        <key value="angabeAUseitErstbescheinigung" />
...
        <expression value=".........**onsetPeriod**.start.exists()        )" />
        <source value="https://fhir.kbv.de/StructureDefinition/KBV_PR_EAU_Bundle" />
      </constraint>

e.g. An interface for prescriptons
https://simplifier.net/erezept/kbvprerpprescription

      <constraint>
        <key value="-erp-angabeUnfallbetrieb" />
...
        <expression value="extension('unfallkennzeichen').**valueCoding**.code = '2' implies extension('unfallbetrieb').exists()" />
        <source value="https://fhir.kbv.de/StructureDefinition/KBV_PR_ERP_Prescription" />
      </constraint>

e.g. An interface for vaccinations
https://simplifier.net/im1x0/kbvprmiovaccinationrecordprime

       <constraint>
        <key value="Occurrence" />
....
        <expression value="**occurrenceDateTime**.toString().length()&gt;=10" />
        <source value="https://fhir.kbv.de/StructureDefinition/KBV_PR_MIO_Vaccination_Record_Prime" />
      </constraint>

e.g. An interface for medical records for children
https://simplifier.net/uh1x0/kbvprmiocmrobservationu1u3datetimeofbirth

      <constraint>
        <key value="date-1" />
...
        <expression value="***valueDateTime***.toString().length()&gt;=16" />
        <source value="https://fhir.kbv.de/StructureDefinition/KBV_PR_MIO_CMR_Observation_U1_U3_Date_Time_of_Birth|1.0.1" />
      </constraint>

a lot more examples are available....And a lot more interfaces will probably face such problems.

In this case a transition phase up to 01.07.2022 is necessary

view this post on Zulip Maximilian Reith (Sep 01 2021 at 11:35):

@Grahame Grieve
i added your reference afterwards, so it may not have worked. This is an important topic for us.

view this post on Zulip Maximilian Reith (Sep 03 2021 at 07:30):

By the way: The first bracket looks a bit weird or not?
is https://www.hl7.org/fhir/fhirpath.html#polymorphism :
(Observation.value as Quantity).unit

should be?
Observation.(value as Quantity).unit

view this post on Zulip Lee Surprenant (Sep 03 2021 at 11:21):

Observation.(value as Quantity).unit

I think not. as (and in) are both functions and operators in fhirpath. you could do (Observation.value as Quantity).unit or Observation.value.as(Quantity).unit but Observation.(value as Quantity).unit doesn't look right to me

view this post on Zulip Maximilian Reith (Sep 06 2021 at 06:48):

okay thanks

view this post on Zulip Maximilian Reith (Sep 07 2021 at 06:28):

the validator might not work properly in context of an extension

We have a chance to update one of our interfaces, so i tried to correct this constraint:

FHIR-Profile_V1.0.2\KBV_PR_ERP_Prescription_ConstraintsNeu.xml (in attached zip)

In line 599 to 612 two variants of this constraint are available:

This part is working properly, but this my be outdated in future:
(extension('https://fhir.kbv.de/StructureDefinition/KBV_EX_ERP_DosageFlag').empty() or extension('https://fhir.kbv.de/StructureDefinition/KBV_EX_ERP_DosageFlag').value.as(Boolean)=false) implies text.empty()

The second is not working:
(extension('https://fhir.kbv.de/StructureDefinition/KBV_EX_ERP_DosageFlag').empty() or (extension('https://fhir.kbv.de/StructureDefinition/KBV_EX_ERP_DosageFlag').value as Boolean)=false) implies text.empty()

Version 5.5.1
java -jar validator_cli.jar -ig FHIR-Profile_V1.0.2 -recurse -version 4.0.1 tset1.xml
FHIR-Profile_V1.0.2.zip

view this post on Zulip Maximilian Reith (Sep 08 2021 at 16:45):

Could somebody confirm this?

view this post on Zulip Grahame Grieve (Sep 14 2021 at 10:57):

can you provide a whole test case - an instance and a profile?

view this post on Zulip Grahame Grieve (Sep 14 2021 at 10:57):

@Maximilian Reith

view this post on Zulip Maximilian Reith (Sep 15 2021 at 06:11):

@Grahame Grieve
yes of course. it is already in the attached zip (3 posts up). tset1.xml is the instance and the profile is in the zip too in directory FHIR-Profile_V1.0.2\KBV_PR_ERP_Prescription_ConstraintsNeu.

view this post on Zulip Maximilian Reith (Sep 15 2021 at 06:12):

just use the mentioned command: java -jar validator_cli.jar -ig FHIR-Profile_V1.0.2 -recurse -version 4.0.1 tset1.xml

view this post on Zulip Maximilian Reith (Sep 16 2021 at 04:54):

i will provide a test case here: https://github.com/FHIR/fhir-test-cases/tree/master/validator

view this post on Zulip Maximilian Reith (Sep 27 2021 at 14:45):

I talked to @Patrick Werner and @Alexander Zautke . They told me a "lenient"-mode is available in HAPI. That would be a solution for us if it supports all type[x] (e.g. value[x], effected[x]) elements. But the lenient-mode needs to be integrated into the cli-validator, before the "hard" type[x]-check is implemented. Even HL7-Germany is affected by this issue.

view this post on Zulip Brian Postlethwaite (Mar 08 2022 at 19:37):

(and this one too @Lloyd)
image.png


Last updated: Apr 12 2022 at 19:14 UTC