mirror of
https://github.com/hapifhir/org.hl7.fhir.core.git
synced 2025-02-13 08:14:46 +00:00
show message ids in validator + advisor documentation
This commit is contained in:
parent
4241fc9d7f
commit
cbb645b9e0
@ -106,8 +106,8 @@ import org.hl7.fhir.validation.cli.utils.ProfileLoader;
|
||||
import org.hl7.fhir.validation.cli.utils.QuestionnaireMode;
|
||||
import org.hl7.fhir.validation.cli.utils.SchemaValidator;
|
||||
import org.hl7.fhir.validation.cli.utils.ValidationLevel;
|
||||
import org.hl7.fhir.validation.instance.BasePolicyAdvisorForFullValidation;
|
||||
import org.hl7.fhir.validation.instance.InstanceValidator;
|
||||
import org.hl7.fhir.validation.instance.advisor.BasePolicyAdvisorForFullValidation;
|
||||
import org.hl7.fhir.validation.instance.utils.ValidationContext;
|
||||
import org.hl7.fhir.utilities.ByteProvider;
|
||||
import org.xml.sax.SAXException;
|
||||
@ -218,6 +218,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
||||
@Getter @Setter private boolean noUnicodeBiDiControlChars;
|
||||
@Getter @Setter private boolean securityChecks;
|
||||
@Getter @Setter private boolean crumbTrails;
|
||||
@Getter @Setter private boolean showMessageIds;
|
||||
@Getter @Setter private boolean forPublication;
|
||||
@Getter @Setter private boolean allowExampleUrls;
|
||||
@Getter @Setter private boolean showMessagesFromReferences;
|
||||
|
@ -120,6 +120,9 @@ public class CliContext {
|
||||
@JsonProperty("crumbTrails")
|
||||
private boolean crumbTrails = false;
|
||||
|
||||
@JsonProperty("showMessageIds")
|
||||
private boolean showMessageIds = false;
|
||||
|
||||
@JsonProperty("forPublication")
|
||||
private boolean forPublication = false;
|
||||
|
||||
@ -719,6 +722,14 @@ public class CliContext {
|
||||
this.crumbTrails = crumbTrails;
|
||||
}
|
||||
|
||||
public boolean isShowMessageIds() {
|
||||
return showMessageIds;
|
||||
}
|
||||
|
||||
public void setShowMessageIds(boolean showMessageIds) {
|
||||
this.showMessageIds = showMessageIds;
|
||||
}
|
||||
|
||||
public boolean isForPublication() {
|
||||
return forPublication;
|
||||
}
|
||||
@ -827,6 +838,7 @@ public class CliContext {
|
||||
Objects.equals(profiles, that.profiles) &&
|
||||
Objects.equals(sources, that.sources) &&
|
||||
Objects.equals(crumbTrails, that.crumbTrails) &&
|
||||
Objects.equals(showMessageIds, that.showMessageIds) &&
|
||||
Objects.equals(forPublication, that.forPublication)&&
|
||||
Objects.equals(allowExampleUrls, that.allowExampleUrls) &&
|
||||
Objects.equals(showTimes, that.showTimes) &&
|
||||
@ -847,7 +859,7 @@ public class CliContext {
|
||||
public int hashCode() {
|
||||
return Objects.hash(baseEngine, doNative, extensions, hintAboutNonMustSupport, recursive, doDebug, assumeValidRestReferences, canDoNative, noInternalCaching,
|
||||
noExtensibleBindingMessages, noInvariants, displayWarnings, wantInvariantsInMessages, map, output, outputSuffix, htmlOutput, txServer, sv, txLog, txCache, mapLog, lang, srcLang, tgtLang, fhirpath, snomedCT,
|
||||
targetVer, igs, questionnaireMode, level, profiles, sources, inputs, mode, locale, locations, crumbTrails, forPublication, showTimes, allowExampleUrls, outputStyle, jurisdiction, noUnicodeBiDiControlChars,
|
||||
targetVer, igs, questionnaireMode, level, profiles, sources, inputs, mode, locale, locations, crumbTrails, showMessageIds, forPublication, showTimes, allowExampleUrls, outputStyle, jurisdiction, noUnicodeBiDiControlChars,
|
||||
watchMode, watchScanDelay, watchSettleTime, bestPracticeLevel, unknownCodeSystemsCauseErrors, noExperimentalContent, htmlInMarkdownCheck, allowDoubleQuotesInFHIRPath, checkIPSCodes);
|
||||
}
|
||||
|
||||
@ -892,6 +904,7 @@ public class CliContext {
|
||||
", mode=" + mode +
|
||||
", securityChecks=" + securityChecks +
|
||||
", crumbTrails=" + crumbTrails +
|
||||
", showMessageIds=" + showMessageIds +
|
||||
", forPublication=" + forPublication +
|
||||
", outputStyle=" + outputStyle +
|
||||
", jurisdiction=" + jurisdiction +
|
||||
|
@ -10,7 +10,7 @@ public class CSVRenderer extends ValidationOutputRenderer {
|
||||
@Override
|
||||
public void start(boolean moreThanOne) {
|
||||
super.start(moreThanOne);
|
||||
dst.println("file, line, col, level, message");
|
||||
dst.println("file, line, col, level, message"+(showMessageIds ? "message-id" : ""));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -19,7 +19,8 @@ public class CSVRenderer extends ValidationOutputRenderer {
|
||||
for (OperationOutcome.OperationOutcomeIssueComponent issue : oo.getIssue()) {
|
||||
int line = ToolingExtensions.readIntegerExtension(issue, ToolingExtensions.EXT_ISSUE_LINE, -1);
|
||||
int col = ToolingExtensions.readIntegerExtension(issue, ToolingExtensions.EXT_ISSUE_COL, -1);
|
||||
dst.println(file+", " + (line == -1 ? "" : Integer.toString(line)) + ", " + (col == -1 ? "" : Integer.toString(col))+", "+issue.getSeverity().getDisplay()+", \""+issue.getDetails().getText()+"\"");
|
||||
dst.println(file+", " + (line == -1 ? "" : Integer.toString(line)) + ", " + (col == -1 ? "" : Integer.toString(col))+", "+issue.getSeverity().getDisplay()+", \""+issue.getDetails().getText()+"\""+
|
||||
(showMessageIds ? "," +issue.getExtensionString("http://hl7.org/fhir/StructureDefinition/operationoutcome-message-id") : ""));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,9 @@ public class CompactRenderer extends ValidationOutputRenderer {
|
||||
String path = issue.hasExpression() ? issue.getExpression().get(0).asStringValue() : "n/a";
|
||||
int line = ToolingExtensions.readIntegerExtension(issue, ToolingExtensions.EXT_ISSUE_LINE, -1);
|
||||
int col = ToolingExtensions.readIntegerExtension(issue, ToolingExtensions.EXT_ISSUE_COL, -1);
|
||||
lines.add(Utilities.padLeft(Integer.toString(line), '0', 8) + ":" + Utilities.padLeft(Integer.toString(col), '0', 8)+":"+path+"|["+Integer.toString(line) + ", " + Integer.toString(col)+"] "+path+": "+issue.getSeverity().getDisplay()+" - "+issue.getDetails().getText());
|
||||
lines.add(Utilities.padLeft(Integer.toString(line), '0', 8) + ":" + Utilities.padLeft(Integer.toString(col), '0', 8)+":"+
|
||||
path+"|["+Integer.toString(line) + ", " + Integer.toString(col)+"] "+path+": "+issue.getSeverity().getDisplay()+" - "+issue.getDetails().getText()+
|
||||
renderMessageId(issue));
|
||||
}
|
||||
Collections.sort(lines);
|
||||
for (String s : lines) {
|
||||
|
@ -34,7 +34,7 @@ public class DefaultRenderer extends ValidationOutputRenderer {
|
||||
}
|
||||
dst.println((error == 0 ? "Success" : "*FAILURE*") + ": " + Integer.toString(error) + " errors, " + Integer.toString(warn) + " warnings, " + Integer.toString(info) + " notes");
|
||||
for (OperationOutcome.OperationOutcomeIssueComponent issue : oo.getIssue()) {
|
||||
dst.println(getIssueSummary(issue));
|
||||
dst.println(getIssueSummary(issue)+renderMessageId(issue));
|
||||
ValidationMessage vm = (ValidationMessage) issue.getUserData("source.msg");
|
||||
if (vm != null && vm.sliceText != null && (crumbTrails || vm.isCriticalSignpost())) {
|
||||
for (String s : vm.sliceText) {
|
||||
|
@ -13,6 +13,7 @@ public abstract class ValidationOutputRenderer {
|
||||
protected boolean crumbTrails;
|
||||
protected boolean moreThanOne;
|
||||
protected PrintStream dst;
|
||||
protected boolean showMessageIds;
|
||||
|
||||
public boolean isCrumbTrails() {
|
||||
return crumbTrails;
|
||||
@ -22,6 +23,14 @@ public abstract class ValidationOutputRenderer {
|
||||
this.crumbTrails = crumbTrails;
|
||||
}
|
||||
|
||||
public boolean isShowMessageIds() {
|
||||
return showMessageIds;
|
||||
}
|
||||
|
||||
public void setShowMessageIds(boolean showMessageIds) {
|
||||
this.showMessageIds = showMessageIds;
|
||||
}
|
||||
|
||||
public String getRunDate() {
|
||||
return runDate;
|
||||
}
|
||||
@ -56,4 +65,10 @@ public abstract class ValidationOutputRenderer {
|
||||
public abstract String getStyleCode();
|
||||
|
||||
public abstract void setFolder(File dir);
|
||||
|
||||
|
||||
protected String renderMessageId(OperationOutcome.OperationOutcomeIssueComponent issue) {
|
||||
return showMessageIds ? " {" +issue.getExtensionString("http://hl7.org/fhir/StructureDefinition/operationoutcome-message-id")+"}" : "";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ import org.hl7.fhir.utilities.json.parser.JsonParser;
|
||||
import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
|
||||
import org.hl7.fhir.utilities.npm.NpmPackage;
|
||||
import org.hl7.fhir.validation.cli.utils.Common;
|
||||
import org.hl7.fhir.validation.instance.BasePolicyAdvisorForFullValidation;
|
||||
import org.hl7.fhir.validation.instance.advisor.BasePolicyAdvisorForFullValidation;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
|
@ -240,6 +240,7 @@ public class ValidationService {
|
||||
PrintStream dst = null;
|
||||
ValidationOutputRenderer renderer = makeValidationOutputRenderer(cliContext);
|
||||
renderer.setCrumbTrails(validator.isCrumbTrails());
|
||||
renderer.setShowMessageIds(validator.isShowMessageIds());
|
||||
renderer.setRunDate(runDate);
|
||||
if (renderer.isSingleFile()) {
|
||||
if (cliContext.getOutput() == null) {
|
||||
@ -574,6 +575,7 @@ public class ValidationService {
|
||||
validationEngine.setWantInvariantInMessage(cliContext.isWantInvariantsInMessages());
|
||||
validationEngine.setSecurityChecks(cliContext.isSecurityChecks());
|
||||
validationEngine.setCrumbTrails(cliContext.isCrumbTrails());
|
||||
validationEngine.setShowMessageIds(cliContext.isShowMessageIds());
|
||||
validationEngine.setForPublication(cliContext.isForPublication());
|
||||
validationEngine.setShowTimes(cliContext.isShowTimes());
|
||||
validationEngine.setAllowExampleUrls(cliContext.isAllowExampleUrls());
|
||||
|
@ -80,6 +80,7 @@ public class Params {
|
||||
public static final String WANT_INVARIANTS_IN_MESSAGES = "-want-invariants-in-messages";
|
||||
public static final String SECURITY_CHECKS = "-security-checks";
|
||||
public static final String CRUMB_TRAIL = "-crumb-trails";
|
||||
public static final String SHOW_MESSAGE_IDS = "-show-message-ids";
|
||||
public static final String FOR_PUBLICATION = "-forPublication";
|
||||
public static final String VERBOSE = "-verbose";
|
||||
public static final String SHOW_TIMES = "-show-times";
|
||||
@ -318,6 +319,8 @@ public class Params {
|
||||
cliContext.setSecurityChecks(true);
|
||||
} else if (args[i].equals(CRUMB_TRAIL)) {
|
||||
cliContext.setCrumbTrails(true);
|
||||
} else if (args[i].equals(SHOW_MESSAGE_IDS)) {
|
||||
cliContext.setShowMessageIds(true);
|
||||
} else if (args[i].equals(FOR_PUBLICATION)) {
|
||||
cliContext.setForPublication(true);
|
||||
} else if (args[i].equals(UNKNOWN_CODESYSTEMS_CAUSE_ERROR)) {
|
||||
@ -326,6 +329,7 @@ public class Params {
|
||||
cliContext.setNoExperimentalContent(true);
|
||||
} else if (args[i].equals(VERBOSE)) {
|
||||
cliContext.setCrumbTrails(true);
|
||||
cliContext.setShowMessageIds(true);
|
||||
} else if (args[i].equals(ALLOW_EXAMPLE_URLS)) {
|
||||
String bl = args[++i];
|
||||
if ("true".equals(bl)) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package org.hl7.fhir.validation.instance;
|
||||
package org.hl7.fhir.validation.instance.advisor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
|
@ -0,0 +1,77 @@
|
||||
package org.hl7.fhir.validation.instance.advisor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.r5.elementmodel.Element;
|
||||
import org.hl7.fhir.r5.elementmodel.Element.SpecialElement;
|
||||
import org.hl7.fhir.r5.model.ElementDefinition;
|
||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.utils.validation.IMessagingServices;
|
||||
import org.hl7.fhir.r5.utils.validation.IResourceValidator;
|
||||
import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor;
|
||||
import org.hl7.fhir.r5.utils.validation.constants.BindingKind;
|
||||
import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPolicy;
|
||||
import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
|
||||
import org.hl7.fhir.utilities.json.JsonException;
|
||||
import org.hl7.fhir.utilities.json.model.JsonObject;
|
||||
import org.hl7.fhir.utilities.json.parser.JsonParser;
|
||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||
|
||||
public class JsonDrivenPolicyAdvisor implements IValidationPolicyAdvisor {
|
||||
|
||||
private JsonObject config;
|
||||
private IValidationPolicyAdvisor base;
|
||||
|
||||
public JsonDrivenPolicyAdvisor(IValidationPolicyAdvisor base, JsonObject config) {
|
||||
this.base = base;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public JsonDrivenPolicyAdvisor(String config) throws JsonException, IOException {
|
||||
this.config = JsonParser.parseObject(config, true);
|
||||
}
|
||||
|
||||
public JsonDrivenPolicyAdvisor(File config) throws JsonException, IOException {
|
||||
this.config = JsonParser.parseObject(new FileInputStream(config), true);
|
||||
}
|
||||
|
||||
public JsonDrivenPolicyAdvisor(FileInputStream config) throws JsonException, IOException {
|
||||
this.config = JsonParser.parseObject(config, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReferenceValidationPolicy policyForReference(IResourceValidator validator, Object appContext, String path, String url) {
|
||||
return base.policyForReference(validator, appContext, path, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContainedReferenceValidationPolicy policyForContained(IResourceValidator validator, Object appContext, StructureDefinition structure, ElementDefinition element, String containerType, String containerId, SpecialElement containingResourceType, String path, String url) {
|
||||
return base.policyForContained(validator, appContext, structure, element, containerType, containerId, containingResourceType, path, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<ResourceValidationAction> policyForResource(IResourceValidator validator, Object appContext, StructureDefinition type, String path) {
|
||||
return base.policyForResource(validator, appContext, type, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<ElementValidationAction> policyForElement(IResourceValidator validator, Object appContext, StructureDefinition structure, ElementDefinition element, String path) {
|
||||
return base.policyForElement(validator, appContext, structure, element, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumSet<CodedContentValidationAction> policyForCodedContent(IResourceValidator validator, Object appContext, String stackPath, ElementDefinition definition, StructureDefinition structure, BindingKind kind, AdditionalBindingPurpose purpose, ValueSet valueSet, List<String> systems) {
|
||||
return base.policyForCodedContent(validator, appContext, stackPath, definition, structure, kind, purpose, valueSet, systems);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StructureDefinition> getImpliedProfilesForResource(IResourceValidator validator, Object appContext, String stackPath, ElementDefinition definition, StructureDefinition structure, Element resource, boolean valid, IMessagingServices msgServices, List<ValidationMessage> messages) {
|
||||
return base.getImpliedProfilesForResource(validator, appContext, stackPath, definition, structure, resource, valid, msgServices, messages);
|
||||
}
|
||||
|
||||
}
|
204
org.hl7.fhir.validation/src/main/resources/help/advisor.txt
Normal file
204
org.hl7.fhir.validation/src/main/resources/help/advisor.txt
Normal file
@ -0,0 +1,204 @@
|
||||
# Introduction
|
||||
|
||||
This document describes the use of the advisor format that advises the validator which rules to enforce.
|
||||
By default the validator enforces the entire FHIR specification as described. Implementers simply wishing
|
||||
to know whether a resource is valid or not should not be using this functionality.
|
||||
|
||||
The advisor functionality exists to assist implementers who are using the validator in pipelines where
|
||||
known issues are tolerated and suppressed. Usually this arises because additional rules were added in
|
||||
later validator versions after design decision had been made, and the specific issues cannot be rectified,
|
||||
though there are other reasons.
|
||||
|
||||
Warning: Implementers use this functionality to hide known issues with their resources.
|
||||
|
||||
There are two ways to turn off validation rules:
|
||||
|
||||
* Suppressing output messages
|
||||
* Controlling what validation runs
|
||||
|
||||
## Suppressing Output Messages
|
||||
|
||||
This approach is conceptually simple: the entire validation is executed, and then
|
||||
messages are filtered from the output based on their messageId.
|
||||
|
||||
The messageId is not usually shown; use the command line parameter ```-show-message-ids``` to show
|
||||
the messageIds in the output. use the command line parameter ```-rules {filename}``` to make a set of
|
||||
rules apply.
|
||||
|
||||
Some notes on this approach:
|
||||
|
||||
* This turns off all uses of that message id - there's no way to be selective about what context they occur in
|
||||
* the messageId is directly tied to the format of the message. For some messages, there are multiple variants of the message, each with their own id, and these all need to be suppressed
|
||||
* message ids are stable, but sometimes an existing message is improved in some contexts, and new message ids are introduced in later versions
|
||||
* the underlying validation still happens, even when the messages are suppressed
|
||||
|
||||
|
||||
## Controlling what validation runs
|
||||
|
||||
An alternative approach is to control what parts of the validation logic are executed.
|
||||
As each step of the validation process occurs, the validator looks in the advisor file
|
||||
to see whether any applicable rules apply at the point it is at, and proceeds as advised
|
||||
by the rules in the advisor file.
|
||||
|
||||
# Validation Rules
|
||||
|
||||
The validator uses several different kinds of rules:
|
||||
|
||||
* resource: what to do when validating a resource
|
||||
* element: what to do when validating an element
|
||||
* invariant: what to when checking an invariant
|
||||
* coded: what to do when validating a coded element (e.g. an element with a binding)
|
||||
* reference: what to do when validating a reference to another resource
|
||||
* contained: what to do when validating a contained resource
|
||||
|
||||
Each rule comes with a set of filters that decide whether the rule applies in a given context, and a set of options to choose from
|
||||
|
||||
## resource
|
||||
|
||||
What to do when validating a resource
|
||||
|
||||
Filters:
|
||||
* path: the path in/from the validated resource where this resource is found. For the validated resource itself, this is the type of the resource, but for contained/referenced resource etc, this can be a complex path
|
||||
* type: the type of the resource e.g. Patient
|
||||
|
||||
Options:
|
||||
* base: validate against the base standard
|
||||
* stated: validate against the profiles stated in the parameters to the validator
|
||||
* meta: validate against the profiles stated in the meta element
|
||||
* global: validate against the known global profiles
|
||||
|
||||
## element
|
||||
|
||||
What to do when validating an element
|
||||
|
||||
Filters:
|
||||
* path: the path in/from the validated resource where this element is found
|
||||
* Structure: the url|version for the applicable profile (may be a the base definition of a resource)
|
||||
* id: the element id in the profile
|
||||
|
||||
Options:
|
||||
* cardinality: check the element against it's stated cardinality
|
||||
* invariants: check the element against it's applicable invariants
|
||||
* bindings: check the element against it's applicable bindings (including additional bindings)
|
||||
* fixed: check the element against it's applicable fixed/pattern values
|
||||
|
||||
Note that slicing determination happens irrespective of these options
|
||||
|
||||
## invariant
|
||||
|
||||
What do when evaluating an invariant
|
||||
|
||||
Filters:
|
||||
* path: the path in/from the validated resource where this element is found
|
||||
* Structure: the url|version for the applicable profile (may be a the base definition of a resource)
|
||||
* id: the element id in the profile
|
||||
* key: the key assigned to the invariant
|
||||
|
||||
Options:
|
||||
* check: check the invariant
|
||||
* warning: downgrade to a warning (if it's an error)
|
||||
|
||||
|
||||
## coded
|
||||
|
||||
What to do when validating an element with a binding (including additional bindings)
|
||||
|
||||
Filters:
|
||||
* path: the path in/from the validated resource where this element is found
|
||||
* Structure: the url|version for the applicable profile (may be a the base definition of a resource)
|
||||
* id: the element id in the profile
|
||||
* type: the data type of the element
|
||||
* kind: the binding strength (required, extensible, preferred)
|
||||
* valueSet: the url|version of the valueSet in the binding
|
||||
* system: a code system in the coded element (note: system isn't known at the decision point for `code` datatypes)
|
||||
|
||||
Options:
|
||||
* concepts: check that the concepts are valid
|
||||
* displays: check that the displays are valid
|
||||
* status: check the status of the applicable value sets and code systems
|
||||
|
||||
## reference
|
||||
|
||||
what to do when validating a reference
|
||||
|
||||
Filters:
|
||||
* path: the path in/from the validated resource where this element is found
|
||||
* Structure: the url|version for the applicable profile (may be a the base definition of a resource)
|
||||
* id: the element id in the profile
|
||||
* url: the reference itself
|
||||
|
||||
Options:
|
||||
* exists: check that the reference can be resolved
|
||||
* type: check that the reference resolves to something of the correct type
|
||||
* valid: validate the target of the reference against any applicable profiles
|
||||
|
||||
## contained
|
||||
|
||||
what to do when validating a contained resource
|
||||
|
||||
Filters:
|
||||
* path: the path in/from the validated resource where this contained resource is found
|
||||
* kind: the kind of containment (bundled, contained, parameter, outcome)
|
||||
* type: the type of the resource e.g. Patient
|
||||
* id: the id of the resource
|
||||
|
||||
Options:
|
||||
* valid: validate the contained resource
|
||||
|
||||
|
||||
# Format
|
||||
|
||||
There are two supported formats: text, and json.
|
||||
|
||||
Each format presents a list of rules. Rules are evaluated in order, and the first matching rule (all filters are true, or no filters) is used.
|
||||
For each rule, zero or more filters are provided, and a set of options (which may be empty) is specified.
|
||||
|
||||
## Text Format
|
||||
|
||||
The file begins with zero or more suppression statements:
|
||||
|
||||
```
|
||||
- VALIDATION_VAL_STATUS_INCONSISTENT_HINT
|
||||
- MSG_DEPRECATED # comments are allowed
|
||||
# comments are allowed here too
|
||||
- This_element_does_not_match_any_known_slice_
|
||||
```
|
||||
|
||||
Then there is zero or more rules. Each rule is a line of text. The line starts with the kind of rule, then a list of name=value pairs for the filters, followed by an ':', and then zero or more options separated by spaces:
|
||||
|
||||
```
|
||||
element (path=Patient.identifier.*): cardinality fixed # comments
|
||||
```
|
||||
|
||||
Comments can also be on empty lines e.g. lines with no rules:
|
||||
|
||||
```
|
||||
# comment
|
||||
```
|
||||
|
||||
## Json format
|
||||
|
||||
```json
|
||||
{
|
||||
"suppress" : ["VALIDATION_VAL_STATUS_INCONSISTENT_HINT", "MSG_DEPRECATED", "This_element_does_not_match_any_known_slice_"],
|
||||
"rules" : [{
|
||||
"type" : "element",
|
||||
"filters" : [{
|
||||
"name" : "path",
|
||||
"value" : "path=Patient.identifier.*"
|
||||
}],
|
||||
"options" : ["cardinality", "fixed"]
|
||||
}]
|
||||
```
|
||||
|
||||
other properties are ignored, so comments etc can be introduced with any other property name
|
||||
|
||||
## Filter matching
|
||||
|
||||
Except for the path, filter matching is string based, using * as the wild card. A filter starting with ^ is treated as a regex that the filter value must match.
|
||||
|
||||
In the path, matching is based on segments, broken up by ```.```. If the path syntax in the filter rule doesn't specify an index, it applies to all occurrences. Indexes can be specified as
|
||||
integer offsets. No selection criteria such as FHIRPath can be used
|
||||
|
||||
# Examples
|
||||
|
@ -93,8 +93,8 @@ import org.hl7.fhir.validation.ValidationEngine;
|
||||
import org.hl7.fhir.validation.ValidatorUtils;
|
||||
import org.hl7.fhir.validation.cli.model.HtmlInMarkdownCheck;
|
||||
import org.hl7.fhir.validation.cli.services.StandAloneValidatorFetcher;
|
||||
import org.hl7.fhir.validation.instance.BasePolicyAdvisorForFullValidation;
|
||||
import org.hl7.fhir.validation.instance.InstanceValidator;
|
||||
import org.hl7.fhir.validation.instance.advisor.BasePolicyAdvisorForFullValidation;
|
||||
import org.hl7.fhir.validation.tests.utilities.TestUtilities;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
|
@ -11,7 +11,7 @@ import org.hl7.fhir.utilities.tests.TestConfig;
|
||||
import org.hl7.fhir.utilities.tests.TestConstants;
|
||||
import org.hl7.fhir.validation.ValidationEngine;
|
||||
import org.hl7.fhir.validation.cli.services.StandAloneValidatorFetcher;
|
||||
import org.hl7.fhir.validation.instance.BasePolicyAdvisorForFullValidation;
|
||||
import org.hl7.fhir.validation.instance.advisor.BasePolicyAdvisorForFullValidation;
|
||||
|
||||
public class TestUtilities {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user