Stream: fhirpath
Topic: 'memberOf' function not implemented yet
Rob Hausam (Dec 04 2019 at 23:00):
The Validator and FHIRPathEngine now seem to be attempting to fully validate ElementDefinition.constraint.expression (which apparently wasn't the case before), resulting in a new error when I build the IPS IG, as the constraint expression that we had in Patient.address.country wasn't actually a valid FHIRPath expression. The human readable for the constraint is "The content of this element SHALL be selected EITHER from ValueSet ISO Country Alpha-2 http://hl7.org/fhir/ValueSet/iso3166-1-2 OR MAY be selected from ISO Country Alpha-3 Value Set http://hl7.org/fhir/ValueSet/iso3166-1-3, IF the country is not specified in value Set ISO Country Alpha-2 http://hl7.org/fhir/ValueSet/iso3166-1-2." I attempted to change it to what I think should be a valid FHIRPath expression:
Patient.address.country.memberOf('http://hl7.org/fhir/ValueSet/iso3166-1-2') or (Patient.address.country.memberOf('http://hl7.org/fhir/ValueSet/iso3166-1-2').not() and Patient.address.country.memberOf('http://hl7.org/fhir/ValueSet/iso3166-1-3'))
But when the IG Publisher attempts to execute the expression it gives this error, indicating that memberOf (documented here) hasn't been implemented:
Validating Resources (00:30.0782) .. validate /Users/rhausam/git-repo/fhir-ips/resources/ig-uv-ips (00:30.0782) .. /Users/rhausam/git-repo/fhir-ips/resources/ig-uv-ips (00:30.0782) .. validate /Users/rhausam/git-repo/fhir-ips/examples/IPS-bundle-01 (00:30.0782) .. /Users/rhausam/git-repo/fhir-ips/examples/IPS-bundle-01 (00:30.0782) validating Bundle/IPS-examples-Bundle-01 (00:30.0782) Exception in thread "main" java.lang.Error: not Implemented yet at org.hl7.fhir.r5.utils.FHIRPathEngine.funcMemberOf(FHIRPathEngine.java:2853) at org.hl7.fhir.r5.utils.FHIRPathEngine.evaluateFunction(FHIRPathEngine.java:2735) at org.hl7.fhir.r5.utils.FHIRPathEngine.execute(FHIRPathEngine.java:1147) at org.hl7.fhir.r5.utils.FHIRPathEngine.execute(FHIRPathEngine.java:1161) at org.hl7.fhir.r5.utils.FHIRPathEngine.execute(FHIRPathEngine.java:1161) at org.hl7.fhir.r5.utils.FHIRPathEngine.execute(FHIRPathEngine.java:1161) at org.hl7.fhir.r5.utils.FHIRPathEngine.evaluate(FHIRPathEngine.java:546) at org.hl7.fhir.r5.utils.FHIRPathEngine.evaluateToBoolean(FHIRPathEngine.java:614) at org.hl7.fhir.r5.validation.InstanceValidator.checkInvariant(InstanceValidator.java:4558) at org.hl7.fhir.r5.validation.InstanceValidator.checkInvariants(InstanceValidator.java:4533) at org.hl7.fhir.r5.validation.InstanceValidator.checkInvariants(InstanceValidator.java:4424) at org.hl7.fhir.r5.validation.InstanceValidator.checkChild(InstanceValidator.java:4148) at org.hl7.fhir.r5.validation.InstanceValidator.validateElement(InstanceValidator.java:4069) at org.hl7.fhir.r5.validation.InstanceValidator.checkChild(InstanceValidator.java:4252) at org.hl7.fhir.r5.validation.InstanceValidator.validateElement(InstanceValidator.java:4069) at org.hl7.fhir.r5.validation.InstanceValidator.start(InstanceValidator.java:2998) at org.hl7.fhir.r5.validation.InstanceValidator.validateResource(InstanceValidator.java:4665) at org.hl7.fhir.r5.validation.InstanceValidator.validateContains(InstanceValidator.java:3976) at org.hl7.fhir.r5.validation.InstanceValidator.checkChild(InstanceValidator.java:4175) at org.hl7.fhir.r5.validation.InstanceValidator.validateElement(InstanceValidator.java:4069) at org.hl7.fhir.r5.validation.InstanceValidator.checkChild(InstanceValidator.java:4180) at org.hl7.fhir.r5.validation.InstanceValidator.validateElement(InstanceValidator.java:4069) at org.hl7.fhir.r5.validation.InstanceValidator.start(InstanceValidator.java:2977) at org.hl7.fhir.r5.validation.InstanceValidator.validateResource(InstanceValidator.java:4665) at org.hl7.fhir.r5.validation.InstanceValidator.validate(InstanceValidator.java:846) at org.hl7.fhir.r5.validation.InstanceValidator.validate(InstanceValidator.java:806) at org.hl7.fhir.igtools.publisher.Publisher.validate(Publisher.java:3972) at org.hl7.fhir.igtools.publisher.Publisher.validate(Publisher.java:3949) at org.hl7.fhir.igtools.publisher.Publisher.createIg(Publisher.java:773) at org.hl7.fhir.igtools.publisher.Publisher.execute(Publisher.java:656) at org.hl7.fhir.igtools.publisher.Publisher.main(Publisher.java:6637)
I assume this is a known issue? Maybe there is a reasonable way to work around this in FHIRPath and still be able to validate that a code is (or isn't) a member of a particular value set? @Bryn Rhodes, or anyone?
Grahame Grieve (Dec 04 2019 at 23:09):
I don't actually understand the fHIRPath. a or a.not or b?
Grahame Grieve (Dec 04 2019 at 23:09):
I don't think the terminology server understands those value sets anyway?
Rob Hausam (Dec 04 2019 at 23:23):
it's actually "a or (a.not and b)"
so it's usually expected to be a, but if it isn't a then it must be b - which I think should make sense
Rob Hausam (Dec 04 2019 at 23:26):
if we need to add support for the code systems / value sets in the terminology server then we should be able to do that - but if we aren't able to check for value set membership then that's not going to help (at least not immediately)
Rob Hausam (Dec 04 2019 at 23:36):
Actually the FHIRPath probably might as well be just "a or b" - the "(a.not and b)" doesn't add anything over just "b" here. Ideally you would want to determine if a particular 3 character code also has a corresponding 2 character code which should be chosen instead, but I don't see an obvious way to do that (unless there is a way with %terminologies.translate, but that might not be supported either?). So if we don't attempt to enforce that aspect then the expression logic is considerably simpler - but the issue of checking the value set membership still remains.
Marco Visser (Dec 05 2019 at 12:13):
So, if I understand correctly with the following example:
<Bundle xmlns="http://hl7.org/fhir"> <id value="bundle1234"/> <type value="searchset"/> <entry> <resource> <Patient> <!-- %rootResource --> <contained> <RelatedPerson> <!-- %resource --> <id value="rel0304"/> <!-- snip --> </RelatedPerson> </contained> <id value="pat3123"/> <!-- snip --> </Patient> </resource> </entry> <!-- snip --> </Bundle>
<Patient> is %rootResource and <RelatedPerson> is %resource ?
Grahame Grieve (Dec 05 2019 at 12:15):
RelatedPerson> is %resourceif the FHIRPath is run in the context of RelatedPerson, yes
Marco Visser (Dec 05 2019 at 12:16):
Thanks Grahame!
Rob Hausam (Dec 05 2019 at 13:15):
Anything more on memberOf? Or any possible workarounds in its absence? @Grahame Grieve @Bryn Rhodes
Bryn Rhodes (Dec 08 2019 at 19:24):
@Rob Hausam , if I'm understanding correctly, the logic you want is actually an xor
. As far as memberOf, if that is not implemented, you could try %terminologies.validateVS
, though that usage is documented as draft.
Rob Hausam (Dec 08 2019 at 22:52):
I don't think 'xor' will provide anything useful here. The value sets are mutually exclusive ( a code is either 2-char or 3-char), and even if they overlapped I don't think you would want to exclude codes that were members of both. Actually I think what would be useful is the value set of 3-char codes without a 2-char equivalent, and then the logic would be "2-char" or "3-char without 2-char equivalent". I agree that %terminologies.validateVS() should also work for this, but I assumed it was even less likely to be implemented than memberOf (because as you say it's documented as draft). But I can check that out.
Grahame Grieve (Dec 09 2019 at 12:24):
have you got a good example set (profile, valid resource, invalid resource)?
Rob Hausam (Dec 09 2019 at 12:55):
Well, maybe - but I'm not entirely sure if I know what you want in this case. Nothing that I have now is provably valid from the build perspective because memberOf isn't implemented (and I haven't had a chance yet to try %terminologies.validateVS). There definitely are invalid and potentially valid versions of the profile.
Grahame Grieve (Dec 09 2019 at 19:16):
so I was asking because I was thinking of implementing memberOf but that means I need test cases
Rob Hausam (Dec 09 2019 at 20:29):
Sure. Let me do a little more work so that the logic actually does what we're looking for and I'll send you a set.
Rob Hausam (Jan 08 2020 at 20:21):
Has this been implemented? I'm no longer getting an error in the IG build when I use memberOf in the constraint expression, but I didn't see anything in the recent FHIRPath commits that addressed it (maybe I missed it). @Bryn Rhodes? @Grahame Grieve?
Grahame Grieve (Jan 09 2020 at 19:48):
I think it's implemented. org.hl7.fhir.r5.utils.FHIRPathEngine L1887
Rob Hausam (Jan 09 2020 at 20:41):
Yes, it appears that it is, as it's working. Do you know when that was done?
Grahame Grieve (Jan 09 2020 at 20:48):
a few weeks back...?
Rob Hausam (Jan 22 2020 at 06:55):
I'm no longer getting the build error, but the memberOf function doesn't appear to be working. I'm getting this warning:
== /Users/rhausam/git-repo/fhir-ips/examples/patient-example-female.xml == WARNING: Patient/patient-example-female: Patient.address[0].country: pat-cnt-2or3-char: The content of this element SHALL be selected EITHER from ValueSet ISO Country Alpha-2 http://hl7.org/fhir/ValueSet/iso3166-1-2 OR MAY be selected from ISO Country Alpha-3 Value Set http://hl7.org/fhir/ValueSet/iso3166-1-3, IF the country is not specified in value Set ISO Country Alpha-2 http://hl7.org/fhir/ValueSet/iso3166-1-2. [Patient.address.country.memberOf('http://hl7.org/fhir/ValueSet/iso3166-1-2') or Patient.address.country.memberOf('http://hl7.org/fhir/ValueSet/iso3166-1-3')]
when I validate this example instance in the build (or separately with the standalone validator):
<?xml version="1.0" encoding="UTF-8"?> <Patient xmlns="http://hl7.org/fhir"> <id value="patient-example-female"/> <identifier> <system value="urn:oid:2.16.840.1.113883.2.4.6.3"/> <value value="574687583"/> </identifier> <active value="true"/> <name> <family value="DeLarosa"/> <given value="Martha"/> </name> <telecom> <system value="phone"/> <value value="+31788700800"/> <use value="home"/> </telecom> <gender value="female"/> <birthDate value="1992-05-01"/> <address> <line value="Laan Van Europa 1600"/> <city value="Dordrecht"/> <postalCode value="3317 DB"/> <country value="NL"/> </address> <contact> <relationship> <coding> <system value="http://terminology.hl7.org/CodeSystem/v3-RoleCode"/> <code value="MTH"/> </coding> </relationship> <name> <family value="Mum"/> <given value="Martha"/> </name> <telecom> <system value="phone"/> <value value="+33-555-20036"/> <use value="home"/> </telecom> <address> <line value="Promenade des Anglais 111"/> <city value="Lyon"/> <postalCode value="69001"/> <country value="FR"/> </address> </contact> </Patient>
The code 'NL' is in fact a valid member of the iso3166-1-2 value set, so I believe the expression should be evaluating to true and no warning should be generated. @Bryn Rhodes? @Grahame Grieve?
Grahame Grieve (Jan 22 2020 at 10:50):
MemberOf is working. I presume this means there’s a problem on the terminology server.
Rob Hausam (Jan 22 2020 at 14:39):
Ok. Not sure yet what that problem is, since the 3166 value sets are displayed properly in the core build, but I will check further.
Rob Hausam (Jan 22 2020 at 14:57):
Hmm. Posting GET `http://tx.fhir.org/r4/ValueSet/$expand?url=http://hl7.org/fhir/ValueSet/iso3166-1-2' works fine, with 'NL' being returned as expected in the expansion. So it doesn't seem like a terminology server error? If memberOf is working (however you test it), is it a problem with the evaluation of the FHIRPath expression? @Grahame Grieve? @Bryn Rhodes?
Grahame Grieve (Jan 22 2020 at 21:34):
I’ll investigate tomorrow
Rob Hausam (Jan 22 2020 at 21:35):
sounds good - thanks
Grahame Grieve (Jan 24 2020 at 05:52):
looks like it works for me. Check these test cases - do you think I missed something? -
https://github.com/FHIR/fhir-test-cases/commit/7a96f17241afb25b94c0db2226a6216df1f090cb
Rob Hausam (Jan 24 2020 at 06:34):
I just did a fresh build with 1.0.47-SNAPSHOT and I'm still getting the warning:
WARNING: Patient/patient-example-female: Patient.address[0].country: pat-cnt-2or3-char: The content of this element SHALL be selected EITHER from ValueSet ISO Country Alpha-2 http://hl7.org/fhir/ValueSet/iso3166-1-2 OR MAY be selected from ISO Country Alpha-3 Value Set http://hl7.org/fhir/ValueSet/iso3166-1-3, IF the country is not specified in value Set ISO Country Alpha-2 http://hl7.org/fhir/ValueSet/iso3166-1-2. [Patient.address.country.memberOf('http://hl7.org/fhir/ValueSet/iso3166-1-2') or Patient.address.country.memberOf('http://hl7.org/fhir/ValueSet/iso3166-1-3')]
Your test cases look fine to me. You are testing exactly what we are doing in IPS, so I don't see why it would be working for you and not for us. Can you check it in IPS, and see if you get the same warning on patient-example-female.xml as we do?
Rob Hausam (Jan 25 2020 at 18:33):
@Grahame Grieve I assume you haven't had a chance yet to look at this again? Let me know if you don't see the issue.
Grahame Grieve (Jan 26 2020 at 10:57):
I don't see the issue. Is it a txCache issue?
Grahame Grieve (Jan 26 2020 at 11:58):
no I do see it and it's a context issue. The context of the expression is Patient.address.country, but the expression is Patient.address.country.memberOf('http://hl7.org/fhir/ValueSet/iso3166-1-2') or Patient.address.country.memberOf('http://hl7.org/fhir/ValueSet/iso3166-1-3')
The path is doubled up
Rob Hausam (Jan 26 2020 at 21:08):
oh, that's interesting - makes sense in retrospect
I guess hadn't thought about whether stating the entire Patient.address.country context was correct (it was already there that way)
that's good to know - thanks
Rob Hausam (Jan 27 2020 at 05:12):
Unfortunately, I'm getting the same exact warning message whether I include the 'Patient.address.country.' part of the path in the expression or not:
WARNING: Patient/patient-example-female: Patient.address[0].country: pat-cnt-2or3-char: The content of this element SHALL be selected EITHER from ValueSet ISO Country Alpha-2 http://hl7.org/fhir/ValueSet/iso3166-1-2 OR MAY be selected from ISO Country Alpha-3 Value Set http://hl7.org/fhir/ValueSet/iso3166-1-3, IF the country is not specified in value Set ISO Country Alpha-2 http://hl7.org/fhir/ValueSet/iso3166-1-2. [memberOf('http://hl7.org/fhir/ValueSet/iso3166-1-2') or memberOf('http://hl7.org/fhir/ValueSet/iso3166-1-3')]
Is there something else that's different?
Rob Hausam (Jan 27 2020 at 05:13):
I'll double check the txCache.
Rob Hausam (Jan 27 2020 at 05:32):
Deleting and re-creating the iso3166 cache by the publisher makes no difference - the cache file has no content.
Rob Hausam (Jan 27 2020 at 16:06):
thanks for fixing this - it looks good now!
Last updated: Apr 12 2022 at 19:14 UTC