Fix bug where some #refs are not resolved to the root of the resource in FHIRPath slicing evaluation

This commit is contained in:
Grahame Grieve 2024-05-09 19:16:33 +10:00
parent 7be94402a5
commit ba3dc45863
2 changed files with 20 additions and 26 deletions

View File

@ -100,4 +100,8 @@ class WorkingContext {
this.noTotal = noTotal; this.noTotal = noTotal;
} }
public void resetTotal() {
total = 0;
}
} }

View File

@ -4644,57 +4644,47 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
private ResolvedReference localResolve(String ref, NodeStack stack, List<ValidationMessage> errors, String path, Element rootResource, Element groupingResource, Element source, BooleanHolder bh) { private ResolvedReference localResolve(String ref, NodeStack stack, List<ValidationMessage> errors, String path, Element rootResource, Element groupingResource, Element source, BooleanHolder bh) {
if (ref.startsWith("#")) { if (ref.startsWith("#")) {
// work back through the parent list. // work back through the parent list, tracking the stack as we go
// really, there should only be one level for this (contained resources cannot contain // really, there should only be one level for this (contained resources cannot contain
// contained resources), but we'll leave that to some other code to worry about // contained resources), but we'll leave that to some other code to worry about
boolean wasContained = false; boolean wasContained = false;
Element focus = stack.getElement();
NodeStack nstack = stack; NodeStack nstack = stack;
while (nstack != null && nstack.getElement() != null) { while (focus != null) {
if (nstack.getElement().getProperty().isResource()) { if (focus.getProperty().isResource()) {
// ok, we'll try to find the contained reference // ok, we'll try to find the contained reference
if (ref.equals("#") && nstack.getElement().getSpecial() != SpecialElement.CONTAINED && wasContained) { if (ref.equals("#") && focus.getSpecial() != SpecialElement.CONTAINED && wasContained) {
ResolvedReference rr = new ResolvedReference(); ResolvedReference rr = new ResolvedReference();
rr.setResource(nstack.getElement()); rr.setResource(focus);
rr.setFocus(nstack.getElement()); rr.setFocus(focus);
rr.setExternal(false); rr.setExternal(false);
rr.setStack(nstack); rr.setStack(nstack);
// rr.getStack().qualifyPath(".ofType("+nstack.getElement().fhirType()+")"); // rr.getStack().qualifyPath(".ofType("+nstack.getElement().fhirType()+")");
// System.out.println("-->"+nstack.getLiteralPath()); // System.out.println("-->"+nstack.getLiteralPath());
return rr; return rr;
} }
if (nstack.getElement().getSpecial() == SpecialElement.CONTAINED) { if (focus.getSpecial() == SpecialElement.CONTAINED) {
wasContained = true; wasContained = true;
} }
IndexedElement res = getContainedById(nstack.getElement(), ref.substring(1)); IndexedElement res = getContainedById(focus, ref.substring(1));
if (res != null) { if (res != null) {
ResolvedReference rr = new ResolvedReference(); ResolvedReference rr = new ResolvedReference();
rr.setResource(nstack.getElement()); rr.setResource(focus);
rr.setFocus(res.getMatch()); rr.setFocus(res.getMatch());
rr.setExternal(false); rr.setExternal(false);
rr.setStack(nstack.push(res.getMatch(), res.getIndex(), res.getMatch().getProperty().getDefinition(), res.getMatch().getProperty().getDefinition())); rr.setStack(nstack.push(res.getMatch(), res.getIndex(), res.getMatch().getProperty().getDefinition(), res.getMatch().getProperty().getDefinition()));
rr.getStack().pathComment(nstack.getElement().fhirType()+"/"+stack.getElement().getIdBase()); rr.getStack().pathComment(res.getMatch().fhirType()+"/"+res.getMatch().getIdBase());
return rr; return rr;
} }
} }
if (nstack.getElement().getSpecial() == SpecialElement.BUNDLE_ENTRY || nstack.getElement().getSpecial() == SpecialElement.PARAMETER) { if (focus.getSpecial() == SpecialElement.BUNDLE_ENTRY || focus.getSpecial() == SpecialElement.PARAMETER) {
return null; // we don't try to resolve contained references across this boundary return null; // we don't try to resolve contained references across this boundary
} }
focus = focus.getParentForValidator();
nstack = nstack.getParent(); nstack = nstack.getParent();
} if (focus != null && nstack == null) {
// try again, and work up the element parent list // we have run off the bottom of the stack, need to fake something
if (ref.equals("#")) { nstack = new NodeStack(context, focus, focus.fhirType(), validationLanguage);
Element e = stack.getElement();
while (e != null) {
if (e.getProperty().isResource() && (e.getSpecial() != SpecialElement.CONTAINED)) {
ResolvedReference rr = new ResolvedReference();
rr.setResource(e);
rr.setFocus(e);
rr.setExternal(false);
rr.setStack(stack.push(e, -1, e.getProperty().getDefinition(), e.getProperty().getDefinition()));
rr.getStack().pathComment(e.fhirType()+"/"+e.getIdBase());
return rr;
}
e = e.getParentForValidator();
} }
} }
return null; return null;