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); }
public static string ConstraintDescription(this ElementDefinition.ConstraintComponent cc) { var desc = cc.Key; if (cc.Human != null) { desc += " \"" + cc.Human + "\""; } return(desc); }
/// <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); } }
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)); } }
public static string GetFhirPathConstraint(this ElementDefinition.ConstraintComponent cc) { return(cc.GetStringExtension("http://hl7.org/fhir/StructureDefinition/structuredefinition-expression")); }
public static bool ValidateInvariantRule(ValidationContext context, ElementDefinition.ConstraintComponent invariantRule, IElementNavigator model, OperationOutcome result) { return(ValidateInvariantRule(context, invariantRule, model.ToTypedElement(), result)); }