From d02362801622bfbda6a9c2ed6a33cea3960c2ebc Mon Sep 17 00:00:00 2001 From: Oliver Egger Date: Wed, 15 May 2019 17:11:50 +0200 Subject: [PATCH 1/3] [gf#21240]: illustrating pattern[x] slices validation problem --- .../validation-examples/manifest.json | 10 + .../observation-bp-localcode.xml | 256 ++++++++++++++++++ ...bservation-bp-profile-twocodesrequired.xml | 256 ++++++++++++++++++ 3 files changed, 522 insertions(+) create mode 100644 org.hl7.fhir.validation/src/test/resources/validation-examples/observation-bp-localcode.xml create mode 100644 org.hl7.fhir.validation/src/test/resources/validation-examples/observation-bp-profile-twocodesrequired.xml diff --git a/org.hl7.fhir.validation/src/test/resources/validation-examples/manifest.json b/org.hl7.fhir.validation/src/test/resources/validation-examples/manifest.json index b16ef0cfe..0ed4962e6 100644 --- a/org.hl7.fhir.validation/src/test/resources/validation-examples/manifest.json +++ b/org.hl7.fhir.validation/src/test/resources/validation-examples/manifest.json @@ -500,6 +500,16 @@ "ERROR: Observation: Profile http://hl7.org/fhir/StructureDefinition/observation-bp-profile, Element 'Observation.component[SystolicBP]': minimum required = 1, but only found 0" ] } + }, + "observation-bp-localcode.xml" : { + "errorCount": 0, + "profile" : { + "source" : "observation-bp-profile-twocodesrequired.xml", + "errorCount": 0, + "errors": [ +// "ERROR: Observation: Profile http://hl7.org/fhir/StructureDefinition/observation-bp-profile, Element 'Observation.component[SystolicBP]': minimum required = 1, but only found 0" + ] + } }, "observation-cholesterol-good.xml" : { "errorCount": 0 diff --git a/org.hl7.fhir.validation/src/test/resources/validation-examples/observation-bp-localcode.xml b/org.hl7.fhir.validation/src/test/resources/validation-examples/observation-bp-localcode.xml new file mode 100644 index 000000000..303269510 --- /dev/null +++ b/org.hl7.fhir.validation/src/test/resources/validation-examples/observation-bp-localcode.xml @@ -0,0 +1,256 @@ + + + + + +
+

+ Generated Narrative with Details +

+

+ id + : blood-pressure +

+

+ meta + : +

+

+ identifier + : urn:uuid:187e0c12-8dd2-67e2-99b2-bf273c878281 +

+

+ basedOn + : +

+

+ status + : final +

+

+ category + : Vital Signs + (Details : + {http://terminology.hl7.org/CodeSystem/observation-category code + 'vital-signs' = 'Vital Signs', given as 'Vital + Signs'}) +

+

+ code: + Blood pressure systolic & diastolic + (Details : {LOINC code '85354-9' = 'Blood pressure + panel with all children optional', given as 'Blood pressure + panel with all children optional'}) +

+

+ subject + : + Patient/example +

+

+ effective + : 17/09/2012 +

+

+ performer + : + Practitioner/example +

+

+ interpretation + : Below low normal + (Details : + {http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation + code 'L' = 'Low', given as 'low'}) +

+

+ bodySite + : Right arm + (Details : {SNOMED CT code '368209003' = 'Right + upper arm', given as 'Right arm'}) +

+
+

+ component +

+

+ code + : Systolic blood pressure + (Details : {LOINC code '8480-6' = 'Systolic blood + pressure', given as 'Systolic blood pressure'}; + {SNOMED CT code '271649006' = 'Systolic blood + pressure', given as 'Systolic blood pressure'}; + {http://acme.org/devices/clinical-codes code 'bp-s' = + 'bp-s', given as 'Systolic Blood pressure'}) + +

+

+ value + : 107 mmHg + (Details: UCUM code mm[Hg] = 'mmHg') +

+

+ interpretation + : Normal + (Details : + {http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation + code 'N' = 'Normal', given as 'normal'}) + +

+
+
+

+ component +

+

+ code + : Diastolic blood pressure + (Details : {LOINC code '8462-4' = 'Diastolic + blood pressure', given as 'Diastolic blood pressure'}) + +

+

+ value + : 60 mmHg + (Details: UCUM code mm[Hg] = 'mmHg') +

+

+ interpretation + : Below low normal + (Details : + {http://terminology.hl7.org/CodeSystem/v3-ObservationInterpretation + code 'L' = 'Low', given as 'low'}) +

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/org.hl7.fhir.validation/src/test/resources/validation-examples/observation-bp-profile-twocodesrequired.xml b/org.hl7.fhir.validation/src/test/resources/validation-examples/observation-bp-profile-twocodesrequired.xml new file mode 100644 index 000000000..bd97a5662 --- /dev/null +++ b/org.hl7.fhir.validation/src/test/resources/validation-examples/observation-bp-profile-twocodesrequired.xml @@ -0,0 +1,256 @@ + + + + +
reworked official bp profile to use + patternCodeableConcept and require a local code system in addition + (http://fhir.ch/ig/local) +
+
+ + + + + <status value="draft" /> + <experimental value="false" /> + <date value="2019-05-06" /> + <publisher + value="Health Level Seven International (Orders and Observations Workgroup)" /> + <contact> + <telecom> + <system value="url" /> + <value + value="http://www.hl7.org/Special/committees/orders/index.cfm Orders and Observations" /> + </telecom> + </contact> + <description value="FHIR Blood Pressure Profile" /> + <fhirVersion value="4.0.0" /> + <mapping> + <identity value="workflow" /> + <uri value="http://hl7.org/fhir/workflow" /> + <name value="Workflow Pattern" /> + </mapping> + <mapping> + <identity value="sct-concept" /> + <uri value="http://snomed.info/conceptdomain" /> + <name value="SNOMED CT Concept Domain Binding" /> + </mapping> + <mapping> + <identity value="v2" /> + <uri value="http://hl7.org/v2" /> + <name value="HL7 v2 Mapping" /> + </mapping> + <mapping> + <identity value="rim" /> + <uri value="http://hl7.org/v3" /> + <name value="RIM Mapping" /> + </mapping> + <mapping> + <identity value="w5" /> + <uri value="http://hl7.org/fhir/fivews" /> + <name value="FiveWs Pattern Mapping" /> + </mapping> + <mapping> + <identity value="sct-attr" /> + <uri value="http://snomed.org/attributebinding" /> + <name value="SNOMED CT Attribute Binding" /> + </mapping> + <kind value="resource" /> + <abstract value="false" /> + <type value="Observation" /> + <baseDefinition + value="http://hl7.org/fhir/StructureDefinition/vitalsigns" /> + <derivation value="constraint" /> + <differential> + <element id="Observation"> + <path value="Observation" /> + <short value="FHIR Blood Pressure Profile" /> + <definition + value="This profile defines how to represent Blood Pressure observations in FHIR using a standard LOINC code and UCUM units of measure. This is a grouping structure. It has no value in Observation.valueQuantity but contains at least one component (systolic and/or diastolic)." /> + <min value="0" /> + <max value="*" /> + </element> + <element id="Observation.code"> + <path value="Observation.code" /> + <short value="Blood Pressure" /> + <definition value="Blood Pressure" /> + <min value="1" /> + <max value="1" /> + <type> + <code value="CodeableConcept" /> + </type> + <patternCodeableConcept> + <coding> + <system value="http://loinc.org" /> + <code value="85354-9" /> + </coding> + <coding> + <system value="http://fhir.ch/ig/local" /> + </coding> + </patternCodeableConcept> + <mustSupport value="true" /> + </element> + <element id="Observation.valueQuantity"> + <path value="Observation.valueQuantity" /> + <min value="0" /> + <max value="0" /> + </element> + <element id="Observation.component"> + <path value="Observation.component" /> + <slicing> + <discriminator> + <type value="pattern" /> + <path value="code" /> + </discriminator> + <rules value="open" /> + </slicing> + <min value="2" /> + <max value="*" /> + </element> + <element id="Observation.component:SystolicBP"> + <path value="Observation.component" /> + <sliceName value="SystolicBP" /> + <short value="SystolicBP" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Observation.component:SystolicBP.code"> + <path value="Observation.component.code" /> + <min value="1" /> + <patternCodeableConcept> + <coding> + <system value="http://loinc.org" /> + <code value="8480-6" /> + </coding> + <coding> + <system value="http://fhir.ch/ig/local" /> + </coding> + </patternCodeableConcept> + </element> + <element id="Observation.component:SystolicBP.valueQuantity"> + <path value="Observation.component.valueQuantity" /> + <type> + <code value="Quantity" /> + </type> + </element> + <element + id="Observation.component:SystolicBP.valueQuantity.value"> + <path value="Observation.component.valueQuantity.value" /> + <min value="1" /> + <max value="1" /> + <type> + <code value="decimal" /> + </type> + <mustSupport value="true" /> + </element> + <element + id="Observation.component:SystolicBP.valueQuantity.unit"> + <path value="Observation.component.valueQuantity.unit" /> + <min value="1" /> + <max value="1" /> + <type> + <code value="string" /> + </type> + <mustSupport value="true" /> + </element> + <element + id="Observation.component:SystolicBP.valueQuantity.system"> + <path value="Observation.component.valueQuantity.system" /> + <min value="1" /> + <max value="1" /> + <type> + <code value="uri" /> + </type> + <fixedUri value="http://unitsofmeasure.org" /> + <mustSupport value="true" /> + </element> + <element + id="Observation.component:SystolicBP.valueQuantity.code"> + <path value="Observation.component.valueQuantity.code" /> + <short + value="Coded responses from the common UCUM units for vital signs value set." /> + <definition + value="Coded responses from the common UCUM units for vital signs value set." /> + <min value="1" /> + <max value="1" /> + <type> + <code value="code" /> + </type> + <fixedCode value="mm[Hg]" /> + <mustSupport value="true" /> + </element> + <element id="Observation.component:DiastolicBP"> + <path value="Observation.component" /> + <sliceName value="DiastolicBP" /> + <short value="DiastolicBP" /> + <min value="1" /> + <max value="1" /> + </element> + <element id="Observation.component:DiastolicBP"> + <path value="Observation.component.code" /> + <min value="1" /> + <patternCodeableConcept> + <coding> + <system value="http://loinc.org" /> + <code value="8462-4" /> + </coding> + <coding> + <system value="http://fhir.ch/ig/local" /> + </coding> + </patternCodeableConcept> + </element> + <element id="Observation.component:DiastolicBP.valueQuantity"> + <path value="Observation.component.valueQuantity" /> + <type> + <code value="Quantity" /> + </type> + </element> + <element + id="Observation.component:DiastolicBP.valueQuantity.value"> + <path value="Observation.component.valueQuantity.value" /> + <min value="1" /> + <max value="1" /> + <type> + <code value="decimal" /> + </type> + <mustSupport value="true" /> + </element> + <element + id="Observation.component:DiastolicBP.valueQuantity.unit"> + <path value="Observation.component.valueQuantity.unit" /> + <min value="1" /> + <max value="1" /> + <type> + <code value="string" /> + </type> + <mustSupport value="true" /> + </element> + <element + id="Observation.component:DiastolicBP.valueQuantity.system"> + <path value="Observation.component.valueQuantity.system" /> + <min value="1" /> + <max value="1" /> + <type> + <code value="uri" /> + </type> + <fixedUri value="http://unitsofmeasure.org" /> + <mustSupport value="true" /> + </element> + <element + id="Observation.component:DiastolicBP.valueQuantity.code"> + <path value="Observation.component.valueQuantity.code" /> + <short + value="Coded responses from the common UCUM units for vital signs value set." /> + <definition + value="Coded responses from the common UCUM units for vital signs value set." /> + <min value="1" /> + <max value="1" /> + <type> + <code value="code" /> + </type> + <fixedCode value="mm[Hg]" /> + <mustSupport value="true" /> + </element> + </differential> +</StructureDefinition> \ No newline at end of file From bf99a3d8e74ec7dc4b0530eba2b02de8739ea11c Mon Sep 17 00:00:00 2001 From: Oliver Egger <oliver.egger@ahdis.ch> Date: Wed, 15 May 2019 17:13:32 +0200 Subject: [PATCH 2/3] [gf#21240]: fixing pattern[x] slices validation --- .../fhir/r5/validation/InstanceValidator.java | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java index fd093cecc..9f0e21f01 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java @@ -2708,30 +2708,33 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat throws DefinitionException { if (cc.hasText()) throw new DefinitionException("Unsupported CodeableConcept pattern - using text - for discriminator(" + discriminator + ") for slice " + ed.getId()); - if (!cc.hasCoding() || cc.getCoding().size() > 1) - throw new DefinitionException("Unsupported CodeableConcept pattern - must be just one coding - for discriminator(" + discriminator + ") for slice " + ed.getId()); - Coding c = cc.getCodingFirstRep(); - if (c.hasExtension() || cc.hasExtension()) + if (!cc.hasCoding()) + throw new DefinitionException("Unsupported CodeableConcept pattern - must have at least one coding - for discriminator(" + discriminator + ") for slice " + ed.getId()); + if (cc.hasExtension()) throw new DefinitionException("Unsupported CodeableConcept pattern - extensions are not allowed - for discriminator(" + discriminator + ") for slice " + ed.getId()); - expression.append(" and " + discriminator + ".coding.where("); - boolean first = true; - if (c.hasSystem()) { - first = false; - expression.append("system = '"+c.getSystem()+"'"); + for(Coding c : cc.getCoding()) { + if (c.hasExtension()) + throw new DefinitionException("Unsupported CodeableConcept pattern - extensions are not allowed - for discriminator(" + discriminator + ") for slice " + ed.getId()); + expression.append(" and " + discriminator + ".coding.where("); + boolean first = true; + if (c.hasSystem()) { + first = false; + expression.append("system = '"+c.getSystem()+"'"); + } + if (c.hasVersion()) { + if (first) first = false; else expression.append(" and "); + expression.append("version = '"+c.getVersion()+"'"); + } + if (c.hasCode()) { + if (first) first = false; else expression.append(" and "); + expression.append("code = '"+c.getCode()+"'"); + } + if (c.hasDisplay()) { + if (first) first = false; else expression.append(" and "); + expression.append("display = '"+c.getDisplay()+"'"); + } + expression.append(").exists()"); } - if (c.hasVersion()) { - if (first) first = false; else expression.append(" and "); - expression.append("version = '"+c.getVersion()+"'"); - } - if (c.hasCode()) { - if (first) first = false; else expression.append(" and "); - expression.append("code = '"+c.getCode()+"'"); - } - if (c.hasDisplay()) { - if (first) first = false; else expression.append(" and "); - expression.append("display = '"+c.getDisplay()+"'"); - } - expression.append(").exists()"); } private void buildFixedExpression(ElementDefinition ed, StringBuilder expression, String discriminator, ElementDefinition criteriaElement) throws DefinitionException { From 43d7de3559673c00447688ef6d70c283b772b8f4 Mon Sep 17 00:00:00 2001 From: Oliver Egger <oliver.egger@ahdis.ch> Date: Wed, 15 May 2019 17:58:34 +0200 Subject: [PATCH 3/3] fix manifest --- .../src/test/resources/validation-examples/manifest.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/org.hl7.fhir.validation/src/test/resources/validation-examples/manifest.json b/org.hl7.fhir.validation/src/test/resources/validation-examples/manifest.json index 0ed4962e6..74e4397e0 100644 --- a/org.hl7.fhir.validation/src/test/resources/validation-examples/manifest.json +++ b/org.hl7.fhir.validation/src/test/resources/validation-examples/manifest.json @@ -505,10 +505,7 @@ "errorCount": 0, "profile" : { "source" : "observation-bp-profile-twocodesrequired.xml", - "errorCount": 0, - "errors": [ -// "ERROR: Observation: Profile http://hl7.org/fhir/StructureDefinition/observation-bp-profile, Element 'Observation.component[SystolicBP]': minimum required = 1, but only found 0" - ] + "errorCount": 0 } }, "observation-cholesterol-good.xml" : {