Don't enforce ids on elements when processing CDA

This commit is contained in:
Grahame Grieve 2024-04-20 23:37:07 +10:00
parent 1c797d64d9
commit 74e5f1d493
3 changed files with 66 additions and 43 deletions

View File

@ -544,6 +544,7 @@ public class ValidationMessage implements Comparator<ValidationMessage>, Compara
private String invId;
private String comment;
private List<ValidationMessage> sliceInfo;
private int count;
/**
* Constructor
@ -661,8 +662,13 @@ public class ValidationMessage implements Comparator<ValidationMessage>, Compara
}
public String getMessage() {
return message;
return message+showCount();
}
private String showCount() {
return count == 0 ? "" : " (also in "+count+" other files)";
}
public ValidationMessage setMessage(String message) {
this.message = message;
return this;
@ -718,20 +724,20 @@ public class ValidationMessage implements Comparator<ValidationMessage>, Compara
}
public String summary() {
return level.toString()+" @ "+location+(line>= 0 && col >= 0 ? " (line "+Integer.toString(line)+", col"+Integer.toString(col)+"): " : ": ") +message +(server != null ? " (src = "+server+")" : "");
return level.toString()+" @ "+location+(line>= 0 && col >= 0 ? " (line "+Integer.toString(line)+", col"+Integer.toString(col)+"): " : ": ") +message+showCount() +(server != null ? " (src = "+server+")" : "");
}
public String toXML() {
return "<message source=\"" + source + "\" line=\"" + line + "\" col=\"" + col + "\" location=\"" + Utilities.escapeXml(location) + "\" type=\"" + type + "\" level=\"" + level + "\" display=\"" + Utilities.escapeXml(getDisplay()) + "\" ><plain>" + Utilities.escapeXml(message) + "</plain><html>" + html + "</html></message>";
return "<message source=\"" + source + "\" line=\"" + line + "\" col=\"" + col + "\" location=\"" + Utilities.escapeXml(location) + "\" type=\"" + type + "\" level=\"" + level + "\" display=\"" + Utilities.escapeXml(getDisplay()) + "\" ><plain>" + Utilities.escapeXml(message)+showCount() + "</plain><html>" + html + "</html></message>";
}
public String getHtml() {
return html == null ? Utilities.escapeXml(message) : html;
return (html == null ? Utilities.escapeXml(message) : html)+showCount();
}
public String getDisplay() {
return level + ": " + (location==null || location.isEmpty() ? "" : (location + ": ")) + message;
return level + ": " + (location==null || location.isEmpty() ? "" : (location + ": ")) + message+showCount();
}
/**
@ -745,7 +751,7 @@ public class ValidationMessage implements Comparator<ValidationMessage>, Compara
b.append("level", level);
b.append("type", type);
b.append("location", location);
b.append("message", message);
b.append("message", message+showCount());
return b.build();
}
@ -955,4 +961,8 @@ public class ValidationMessage implements Comparator<ValidationMessage>, Compara
this.server = server;
}
public void incCount() {
count++;
}
}

View File

@ -489,7 +489,7 @@ Unable_to_handle_system__filter_with_property__ = Unable to handle system {0} fi
Unable_to_resolve_system__value_set_has_include_with_no_system = Unable to resolve system - value set {0} include #{1} has no system
UNABLE_TO_RESOLVE_SYSTEM_SYSTEM_IS_INDETERMINATE = The code system {1} referred to from value set {0} has a grammar, and the code might be valid in it
Unable_to_resolve_system__value_set_has_include_with_unknown_system = The System URI could not be determined for the code ''{0}'' in the ValueSet ''{1}'': include #{2} has system {3} which could not be found, and the server returned error {4}
Unable_to_resolve_system__value_set_has_include_with_filter = The System URI could not be determined for the code ''{0}'' in the ValueSet ''{1}'': include #{2} has a filter on system {3}
Unable_to_resolve_system__value_set_has_include_with_filter = The System URI could not be determined for the code ''{0}'' in the ValueSet ''{1}'': include #{2} has a filter on system {3}: {4}
Unable_to_resolve_system__value_set_has_imports = The System URI could not be determined for the code ''{0}'' in the ValueSet ''{1}'': value set has imports
Unable_to_resolve_system__value_set_has_multiple_matches = The System URI could not be determined for the code ''{0}'' in the ValueSet ''{1}'': value set expansion has multiple matches: {2}
Unable_to_resolve_system__value_set_expansion_has_multiple_systems = The System URI could not be determined for the code ''{0}'' in the ValueSet ''{1}'': value set expansion has multiple systems
@ -1059,7 +1059,8 @@ TERMINOLOGY_TX_UNKNOWN_OID = The OID ''{0}'' is not known, so the code can't be
TERMINOLOGY_TX_SYSTEM_NO_CODE = A code with no system has no defined meaning, and it cannot be validated. A system should be provided
XSI_TYPE_WRONG = The xsi:type value ''{0}'' is wrong (should be ''{1}''). Note that xsi:type is unnecessary at this point
XSI_TYPE_UNNECESSARY = xsi:type is unnecessary at this point
TERMINOLOGY_TX_OID_MULTIPLE_MATCHES = The OID ''{0}'' matches multiple code systems ({1})
TERMINOLOGY_TX_OID_MULTIPLE_MATCHES = The OID ''{0}'' matches multiple resources ({1})
TERMINOLOGY_TX_OID_MULTIPLE_MATCHES_CHOSEN = The OID ''{0}'' matches multiple resources ({2}); {1} was chosen as the most appropriate
CDA_UNKNOWN_TEMPLATE = The CDA Template {0} is not known
CDA_UNKNOWN_TEMPLATE_EXT = The CDA Template {0} / {1} is not known
UNABLE_TO_DETERMINE_TYPE_CONTEXT_INV = The types could not be determined from the extension context, so the invariant can't be validated (types = {0})

View File

@ -70,6 +70,8 @@ import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
import org.hl7.fhir.r5.conformance.profile.ProfileUtilities.SourcedChildDefinitions;
import org.hl7.fhir.r5.context.ContextUtilities;
import org.hl7.fhir.r5.context.IWorkerContext;
import org.hl7.fhir.r5.context.IWorkerContext.OIDDefinition;
import org.hl7.fhir.r5.context.IWorkerContext.OIDSummary;
import org.hl7.fhir.r5.elementmodel.Element;
import org.hl7.fhir.r5.elementmodel.Element.SpecialElement;
import org.hl7.fhir.r5.elementmodel.JsonParser;
@ -1777,17 +1779,21 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
String oid = element.getNamedChildValue("codeSystem", false);
if (oid != null) {
Set<String> urls = context.urlsForOid(true, oid);
if (urls.size() != 1) {
c.setSystem("urn:oid:"+oid);
ok = false;
if (urls.size() == 0) {
OIDSummary urls = context.urlsForOid(oid, "CodeSystem");
if (urls.urlCount() == 1) {
c.setSystem(urls.getUrl());
} else if (urls.urlCount() == 0) {
warning(errors, "2023-10-11", IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_UNKNOWN_OID, oid);
} else {
rule(errors, "2023-10-11", IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_OID_MULTIPLE_MATCHES, oid, CommaSeparatedStringBuilder.join(",", urls));
}
String prefUrl = urls.chooseBestUrl();
if (prefUrl == null) {
rule(errors, "2023-10-11", IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_OID_MULTIPLE_MATCHES, oid, urls.describe());
ok = false;
} else {
c.setSystem(urls.iterator().next());
c.setSystem(prefUrl);
warning(errors, "2023-10-11", IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_OID_MULTIPLE_MATCHES_CHOSEN, oid, prefUrl, urls.describe());
}
}
} else {
warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_SYSTEM_NO_CODE);
@ -6588,18 +6594,21 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
String code = element.getNamedChildValue(isPQ ? "unit" : "code", false);
String oid = isPQ ? "2.16.840.1.113883.6.8" : element.getNamedChildValue("codeSystem", false);
if (oid != null) {
Set<String> urls = context.urlsForOid(true, oid);
if (urls.size() != 1) {
OIDSummary urls = context.urlsForOid(oid, "CodeSystem");
system = "urn:oid:"+oid;
ok = false;
if (urls.size() == 0) {
if (urls.urlCount() == 1) {
system = urls.getUrl();
} else if (urls.urlCount() == 0) {
warning(errors, "2023-10-11", IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_UNKNOWN_OID, oid);
} else {
rule(errors, "2023-10-11", IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_OID_MULTIPLE_MATCHES, oid, CommaSeparatedStringBuilder.join(",", urls));
}
String prefUrl = urls.chooseBestUrl();
if (prefUrl == null) {
rule(errors, "2023-10-11", IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_OID_MULTIPLE_MATCHES, oid, urls.describe());
ok = false;
} else {
system = urls.iterator().next();
system = prefUrl;
warning(errors, "2023-10-11", IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_OID_MULTIPLE_MATCHES_CHOSEN, oid, prefUrl, urls.describe());
}
}
} else {
warning(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, code == null, I18nConstants.TERMINOLOGY_TX_SYSTEM_NO_CODE);
@ -7208,6 +7217,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
// todo: validate everything in this bundle.
}
if (rok) {
// todo: not clear what we should do with regard to logical models - should they have ids? Should we check anything?
if (element.getProperty().getStructure().getKind() != StructureDefinitionKind.LOGICAL) {
if (idstatus == IdStatus.REQUIRED && (element.getNamedChild(ID, false) == null)) {
ok = rule(errors, NO_RULE_DATE, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), false, I18nConstants.RESOURCE_RES_ID_MISSING) && ok;
} else if (idstatus == IdStatus.PROHIBITED && (element.getNamedChild(ID, false) != null)) {
@ -7224,6 +7235,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
}
}
}
// validate
if (rule(errors, NO_RULE_DATE, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), checkResourceName(defn, resourceName, element.getFormat()), I18nConstants.VALIDATION_VAL_PROFILE_WRONGTYPE,
defn.getType(), resourceName, defn.getVersionedUrl())) {
@ -7499,7 +7511,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
// first case: the type value set is wrong for primitive special types
for (OperationOutcomeIssueComponent iss : vr.getIssues()) {
if (iss.hasDetails() && iss.getDetails().getText().startsWith("Unable to resolve system - value set expansion has no matches for code 'http://hl7.org/fhirpath/System")) {
if (iss.hasDetails() && iss.getDetails().hasText() && iss.getDetails().getText().startsWith("Unable to resolve system - value set expansion has no matches for code 'http://hl7.org/fhirpath/System")) {
return new ValidationResult("http://hl7.org/fhirpath/System", null, null, null);
}
}