private static double CompareConstraints(ElementDefinition.ConstraintComponent constraint1, ElementDefinition.ConstraintComponent constraint2)
        {
            double factor = 0;

            if (constraint1.Xpath != constraint2.Xpath)
            {
                return(AspectWeights.WEIGHT_CONSTRAINT_XPATH);
            }
            if (constraint1.Human != constraint2.Human)
            {
                factor += AspectWeights.WEIGHT_CONSTRAINT_HUMAN;
            }
            if (constraint1.Severity != constraint2.Severity)
            {
                factor += AspectWeights.WEIGHT_CONSTRAINT_SEVERITY;
            }
            if (constraint1.Key != constraint2.Key)
            {
                factor += AspectWeights.WEIGHT_CONSTRAINT_KEY;
            }

            if (constraint1.Requirements != constraint2.Requirements)
            {
                factor += AspectWeights.WEIGHT_CONSTRAINT_REQUIREMENTS;
            }

            return(1.0 * factor);
        }
        private static CompiledExpression getExecutableConstraint(Validator v, OperationOutcome outcome, IElementNavigator instance,
                                                                  ElementDefinition.ConstraintComponent constraintElement)
        {
            var compiledExpression = constraintElement.Annotation <CompiledConstraintAnnotation>()?.Expression;

            if (compiledExpression == null)
            {
                var fpExpressionText = constraintElement.GetFhirPathConstraint();

                if (fpExpressionText != null)
                {
                    try
                    {
                        compiledExpression = v.FpCompiler.Compile(fpExpressionText);
                        constraintElement.AddAnnotation(new CompiledConstraintAnnotation {
                            Expression = compiledExpression
                        });
                    }
                    catch (Exception e)
                    {
                        v.Trace(outcome, $"Compilation of FhirPath for constraint '{constraintElement.Key}' failed: {e.Message}",
                                Issue.PROFILE_ELEMENTDEF_INVALID_FHIRPATH_EXPRESSION, instance);
                    }
                }
                else
                {
                    v.Trace(outcome, $"Encountered an invariant ({constraintElement.Key}) that has no FhirPath expression, skipping validation of this constraint",
                            Issue.UNSUPPORTED_CONSTRAINT_WITHOUT_FHIRPATH, instance);
                }
            }

            return(compiledExpression);
        }
예제 #3
0
        public static string ConstraintDescription(this ElementDefinition.ConstraintComponent cc)
        {
            var desc = cc.Key;

            if (cc.Human != null)
            {
                desc += " \"" + cc.Human + "\"";
            }

            return(desc);
        }
예제 #4
0
        /// <summary>
        /// Perform the Invariant based validation for this rule
        /// </summary>
        /// <param name="invariantRule"></param>
        /// <param name="model"></param>
        /// <param name="result">The OperationOutcome that will have the validation results appended</param>
        /// <returns></returns>
        protected static bool ValidateInvariantRule(ElementDefinition.ConstraintComponent invariantRule, IElementNavigator model, OperationOutcome result)
        {
            string expression = invariantRule.GetStringExtension("http://hl7.org/fhir/StructureDefinition/structuredefinition-expression");

            try
            {
                // No FhirPath extension
                if (string.IsNullOrEmpty(expression))
                {
                    result.Issue.Add(new OperationOutcome.IssueComponent()
                    {
                        Code        = OperationOutcome.IssueType.Invariant,
                        Severity    = OperationOutcome.IssueSeverity.Warning,
                        Details     = new CodeableConcept(null, invariantRule.Key, "Unable to validate without a FhirPath expression"),
                        Diagnostics = expression
                    });
                    return(true);
                }

                // Ensure the FHIR extensions are registered
                Hl7.Fhir.FhirPath.PocoNavigatorExtensions.PrepareFhirSybolTableFunctions();

                if (model.Predicate(expression, model))
                {
                    return(true);
                }

                result.Issue.Add(new OperationOutcome.IssueComponent()
                {
                    Code        = OperationOutcome.IssueType.Invariant,
                    Severity    = OperationOutcome.IssueSeverity.Error,
                    Details     = new CodeableConcept(null, invariantRule.Key, invariantRule.Human),
                    Diagnostics = expression
                });
                return(false);
            }
            catch (Exception ex)
            {
                result.Issue.Add(new OperationOutcome.IssueComponent()
                {
                    Code        = OperationOutcome.IssueType.Invariant,
                    Severity    = OperationOutcome.IssueSeverity.Fatal,
                    Details     = new CodeableConcept(null, invariantRule.Key, "FATAL: Unable to process the invariant rule: " + invariantRule.Key + " " + expression),
                    Diagnostics = String.Format("FhirPath: {0}\r\nError: {1}", expression, ex.Message)
                });
                return(false);
            }
        }
예제 #5
0
        public void ParseElementDefinitionConstraint()
        {
            string constraint = "";

            /*
             *    <element>
             *          <constraint>
             *            <extension url="http://hl7.org/fhir/StructureDefinition/structuredefinition-expression">
             *              <valueString value="codeSystem.empty() or (codeSystem.system != url)"/>
             *            </extension>
             *            <key value="vsd-7"/>
             *            <severity value="error"/>
             *            <human value="A defined code system (if present) SHALL have a different url than the value set url"/>
             *            <xpath value="not(f:codeSystem/f:system/@value = f:url/@value)"/>
             *          </constraint>
             *    </element>
             */
            XmlDocument doc = new XmlDocument();

            doc.LoadXml(constraint);
            XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);

            ns.AddNamespace("fhir", "http://hl7.org/fhir");
            foreach (XmlElement node in doc.SelectNodes("fhir:constraint"))
            {
                string expression = node.SelectSingleNode("fhir:extension[url='http://hl7.org/fhir/StructureDefinition/structuredefinition-expression']/fhirString/@value").Value;
                string key        = node.SelectSingleNode("fhir:key/@value").Value;
                string severity   = node.SelectSingleNode("fhir:severity/@value").Value;
                string human      = node.SelectSingleNode("fhir:human/@value").Value;
                string xpath      = node.SelectSingleNode("fhir:xpath/@value").Value;
                var    newConst   = new ElementDefinition.ConstraintComponent()
                {
                    Key      = key,
                    Severity = severity == "Error" ? ElementDefinition.ConstraintSeverity.Error : ElementDefinition.ConstraintSeverity.Warning,
                    Human    = human,
                    Xpath    = xpath
                };
                newConst.AddExtension("http://hl7.org/fhir/StructureDefinition/structuredefinition-expression", new FhirString(expression));
            }
        }
예제 #6
0
 public static string GetFhirPathConstraint(this ElementDefinition.ConstraintComponent cc)
 {
     return(cc.GetStringExtension("http://hl7.org/fhir/StructureDefinition/structuredefinition-expression"));
 }
예제 #7
0
 public static bool ValidateInvariantRule(ValidationContext context, ElementDefinition.ConstraintComponent invariantRule, IElementNavigator model, OperationOutcome result)
 {
     return(ValidateInvariantRule(context, invariantRule, model.ToTypedElement(), result));
 }