Fix id/idref to resolve in document if in a document

This commit is contained in:
Grahame Grieve 2024-09-22 06:40:15 -04:00
parent fedf7e9e6d
commit 3cec189333
5 changed files with 122 additions and 188 deletions

View File

@ -1031,7 +1031,7 @@ VALUESET_SUPPLEMENT_MISSING_one = Required supplement not found: {1}
VALUESET_SUPPLEMENT_MISSING_other = Required supplements not found: {1}
VALUESET_TOO_COSTLY = The value set ''{0}'' expansion has too many codes to display ({1})
VALUESET_TOO_COSTLY_COUNT = The value set ''{0}'' expansion has {2} codes, which is too many to display ({1})
VALUESET_TOO_COSTLY_TIME = The value set ''{0}'' expansion took too long to process (>{1}sec)
VALUESET_TOO_COSTLY_TIME = The value set ''{0}'' {2} took too long to process (>{1}sec)
VALUESET_UNC_SYSTEM_WARNING = Unknown System ''{0}'' specified, so Concepts and Filters can''t be checked (Details: {1})
VALUESET_UNC_SYSTEM_WARNING_VER = Unknown System/Version ''{0}'' specified, so Concepts and Filters can''t be checked (Details: {1})
VALUESET_UNKNOWN_FILTER_PROPERTY = The property ''{0}'' is not known for the system ''{1}'', so may not be understood by the terminology ecosystem. Known properties for this system: {2}

View File

@ -1192,6 +1192,34 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi
}
protected int countFragmentMatches(Element element, String fragment, NodeStack stack) {
int count = countFragmentMatches(element, fragment);
if (count == 0 && element.isResource() && element.hasParentForValidator()) {
Element bnd = getElementBundle(element);
if (bnd != null) {
// in this case, we look into the parent - if there is one - and if it's a bundle, we look at the entries (but not in them)
for (Element be : bnd.getChildrenByName("entry")) {
String id = be.getIdBase();
if (fragment.equals(id)) {
count++;
}
}
}
}
return count;
}
private Element getElementBundle(Element element) {
Element p = element.getParentForValidator();
if (p != null) {
Element b = p.getParentForValidator();
if (b != null && b.fhirType().equals("Bundle")) {
return b;
}
}
return null;
}
protected int countFragmentMatches(Element element, String fragment) {
int count = 0;
if (fragment.equals(element.getIdBase())) {

View File

@ -3193,7 +3193,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
// check that no illegal elements and attributes have been used
ok = checkInnerNames(errors, e, path, xhtml.getChildNodes(), false) && ok;
ok = checkUrls(errors, e, path, xhtml.getChildNodes()) && ok;
ok = checkIdRefs(errors, e, path, xhtml, resource) && ok;
ok = checkIdRefs(errors, e, path, xhtml, resource, node) && ok;
if (true) {
ok = checkReferences(valContext, errors, e, path, "div", xhtml, resource) && ok;
}
@ -3642,11 +3642,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
return ok;
}
private boolean checkIdRefs(List<ValidationMessage> errors, Element e, String path, XhtmlNode node, Element resource) {
private boolean checkIdRefs(List<ValidationMessage> errors, Element e, String path, XhtmlNode node, Element resource, NodeStack stack) {
boolean ok = true;
if (node.getNodeType() == NodeType.Element && node.getAttribute("idref") != null) {
String idref = node.getAttribute("idref");
int count = countFragmentMatches(resource, idref);
int count = countFragmentMatches(resource, idref, stack);
if (count == 0) {
ok = warning(errors, "2023-12-01", IssueType.INVALID, e.line(), e.col(), path, idref == null, I18nConstants.XHTML_IDREF_NOT_FOUND, idref) && ok;
} else if (count > 1) {
@ -3655,7 +3655,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
if (node.hasChildren()) {
for (XhtmlNode child : node.getChildNodes()) {
checkIdRefs(errors, e, path, child, resource);
checkIdRefs(errors, e, path, child, resource, stack);
}
}
return ok;
@ -6067,20 +6067,22 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
Element div = text.getNamedChild("div", false);
if (lang != null && div != null) {
XhtmlNode xhtml = div.getXhtml();
String l = xhtml.getAttribute("lang");
String xl = xhtml.getAttribute("xml:lang");
if (l == null && xl == null) {
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_MISSING1);
} else {
if (l == null) {
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_MISSING2);
} else if (!l.equals(lang)) {
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_DIFFERENT1, lang, l);
}
if (xl == null) {
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_MISSING3);
} else if (!xl.equals(lang)) {
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_DIFFERENT2, lang, xl);
if (xhtml != null) {
String l = xhtml.getAttribute("lang");
String xl = xhtml.getAttribute("xml:lang");
if (l == null && xl == null) {
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_MISSING1);
} else {
if (l == null) {
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_MISSING2);
} else if (!l.equals(lang)) {
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_DIFFERENT1, lang, l);
}
if (xl == null) {
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_MISSING3);
} else if (!xl.equals(lang)) {
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, div.line(), div.col(), stack.getLiteralPath(), false, I18nConstants.LANGUAGE_XHTML_LANG_DIFFERENT2, lang, xl);
}
}
}
}
@ -7615,6 +7617,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
}
public long timeNoTX() {
return (timeTracker.getOverall() - timeTracker.getTxTime()) / 1000000;
}
public String reportTimes() {
String s = String.format("Times (ms): overall = %d:4, tx = %d, sd = %d, load = %d, fpe = %d, spec = %d", timeTracker.getOverall() / 1000000, timeTracker.getTxTime() / 1000000, timeTracker.getSdTime() / 1000000, timeTracker.getLoadTime() / 1000000, timeTracker.getFpeTime() / 1000000, timeTracker.getSpecTime() / 1000000);
timeTracker.reset();
@ -8028,6 +8033,10 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
public void setNoExperimentalContent(boolean noExperimentalContent) {
this.noExperimentalContent = noExperimentalContent;
}
public void resetTimes() {
timeTracker.reset();
}
}

View File

@ -82,3 +82,45 @@ v: {
}
-------------------------------------------------------------------------------------
{"code" : {
"system" : "http://hl7.org/fhir/uv/ips/CodeSystem/absent-unknown-uv-ips",
"code" : "no-allergy-info",
"display" : "No information about allergies"
}, "valueSet" :null, "langs":"en-NZ", "useServer":"true", "useClient":"false", "guessSystem":"false", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
"resourceType" : "Parameters",
"parameter" : [{
"name" : "profile-url",
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
}]
}}####
v: {
"code" : "no-allergy-info",
"system" : "http://hl7.org/fhir/uv/ips/CodeSystem/absent-unknown-uv-ips",
"severity" : "error",
"error" : "A definition for CodeSystem 'http://hl7.org/fhir/uv/ips/CodeSystem/absent-unknown-uv-ips' could not be found, so the code cannot be validated",
"class" : "CODESYSTEM_UNSUPPORTED",
"server" : "http://tx-dev.fhir.org/r4",
"unknown-systems" : "http://hl7.org/fhir/uv/ips/CodeSystem/absent-unknown-uv-ips",
"issues" : {
"resourceType" : "OperationOutcome",
"issue" : [{
"extension" : [{
"url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server",
"valueUrl" : "http://tx-dev.fhir.org/r4"
}],
"severity" : "error",
"code" : "not-found",
"details" : {
"coding" : [{
"system" : "http://hl7.org/fhir/tools/CodeSystem/tx-issue-type",
"code" : "not-found"
}],
"text" : "A definition for CodeSystem 'http://hl7.org/fhir/uv/ips/CodeSystem/absent-unknown-uv-ips' could not be found, so the code cannot be validated"
},
"location" : ["Coding.system"],
"expression" : ["Coding.system"]
}]
}
}
-------------------------------------------------------------------------------------