diff --git a/org.hl7.fhir.core.generator/src/org/hl7/fhir/core/generator/codegen/extensions/JavaExtensionsFactoryGenerator.java b/org.hl7.fhir.core.generator/src/org/hl7/fhir/core/generator/codegen/extensions/JavaExtensionsFactoryGenerator.java index 3c59a38c9..f932e2b2f 100644 --- a/org.hl7.fhir.core.generator/src/org/hl7/fhir/core/generator/codegen/extensions/JavaExtensionsFactoryGenerator.java +++ b/org.hl7.fhir.core.generator/src/org/hl7/fhir/core/generator/codegen/extensions/JavaExtensionsFactoryGenerator.java @@ -98,7 +98,7 @@ public class JavaExtensionsFactoryGenerator extends JavaBaseGenerator { ElementDefinition edRoot = sd.getSnapshot().getElementFirstRep(); boolean repeats = !edRoot.getMax().equals("1"); String verb = repeats ? "add" : "set"; - ElementDefinition edValue = sd.getSnapshot().getElementByPath("Extension.value[x]"); + ElementDefinition edValue = sd.getSnapshot().getElementByPath("Extension.value[x]", false); List types = analyseTypes(edValue); if (types.size() > 5) { src.append(" public static Extension make"+name+"(DataType value) {\r\n"); diff --git a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/renderers/DataRenderer.java b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/renderers/DataRenderer.java index 56cd3c6bd..3610c2fa7 100644 --- a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/renderers/DataRenderer.java +++ b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/renderers/DataRenderer.java @@ -338,7 +338,7 @@ public class DataRenderer extends Renderer { StructureDefinition sd = getContext().getWorker().fetchTypeDefinition(t); if (sd == null) return false; - if (Utilities.existsInList(t, VersionUtilities.getCanonicalResourceNames(getContext().getWorker().getVersion()))) { + if (VersionUtilities.getCanonicalResourceNames(getContext().getWorker().getVersion()).contains(t)) { return true; } if (Utilities.existsInList(t, diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java index b3e384870..9d8809b5d 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java @@ -3969,12 +3969,12 @@ public class ProfileUtilities extends TranslatingUtilities { if (!isExtensionDefinition(sd)) { return false; } - ElementDefinition value = sd.getSnapshot().getElementByPath("Extension.value"); + ElementDefinition value = sd.getSnapshot().getElementByPath("Extension.value", true); return value != null && !value.isProhibited(); } public static boolean isModifierExtension(StructureDefinition sd) { - ElementDefinition defn = sd.getSnapshot().getElementByPath("Extension"); + ElementDefinition defn = sd.getSnapshot().getElementByPath("Extension", true); return defn.getIsModifier(); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java index 3937253a3..807eb8681 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java @@ -1457,7 +1457,7 @@ public class Element extends Base { if (property.getStructure().hasExtension(ToolingExtensions.EXT_RESOURCE_IMPLEMENTS)) { StructureDefinition sd = property.getContext().fetchResource(StructureDefinition.class, ExtensionsUtils.getExtensionString(property.getStructure(), ToolingExtensions.EXT_RESOURCE_IMPLEMENTS)); if (sd != null) { - ElementDefinition ed = sd.getSnapshot().getElementByPath(property.getDefinition().getPath().replace(property.getStructure().getType(), sd.getType())); + ElementDefinition ed = sd.getSnapshot().getElementByPath(property.getDefinition().getPath().replace(property.getStructure().getType(), sd.getType()), true); if (ed != null) { return ed.getBase().getPath(); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java index 4815ded2b..255a75c3a 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java @@ -1233,12 +1233,15 @@ public class StructureDefinition extends CanonicalResource { // added from java-adornments.txt: - public ElementDefinition getElementByPath(String path) { + public ElementDefinition getElementByPath(String path, boolean autoChoice) { + if (autoChoice && path.endsWith("[x]")) { + path = path.substring(0, path.length()-3); + } if (path == null) { return null; } for (ElementDefinition ed : getElement()) { - if (path.equals(ed.getPath()) || (path+"[x]").equals(ed.getPath())) { + if (path.equals(ed.getPath()) || (autoChoice && (path+"[x]").equals(ed.getPath()))) { return ed; } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java index 911c390e4..7fbb0eb4f 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java @@ -129,7 +129,7 @@ public abstract class PEDefinition { type= type.substring(0, type.indexOf(".")); } StructureDefinition sd = builder.getContext().fetchTypeDefinition(type); - return sd.getSnapshot().getElementByPath(definition.getBase().getPath()); + return sd.getSnapshot().getElementByPath(definition.getBase().getPath(), true); } /** diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionExtension.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionExtension.java index bb66d9d8f..59d357191 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionExtension.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionExtension.java @@ -21,8 +21,8 @@ public class PEDefinitionExtension extends PEDefinition { super(builder, name, profile, definition, ppath); this.sliceDefinition = sliceDefinition; this.extension= extension; - eed = extension.getSnapshot().getElementByPath("Extension.extension"); - ved = extension.getSnapshot().getElementByPath("Extension.value[x]"); + eed = extension.getSnapshot().getElementByPath("Extension.extension", true); + ved = extension.getSnapshot().getElementByPath("Extension.value[x]", true); } @Override diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java index d277cd283..3a28f75bc 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java @@ -375,7 +375,7 @@ public class DataRenderer extends Renderer implements CodeResolver { StructureDefinition sd = getContext().getWorker().fetchTypeDefinition(t); if (sd == null) return false; - if (Utilities.existsInList(t, VersionUtilities.getCanonicalResourceNames(getContext().getWorker().getVersion()))) { + if (VersionUtilities.getCanonicalResourceNames(getContext().getWorker().getVersion()).contains(t)) { return true; } if (Utilities.existsInList(t, diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValueSetValidator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValueSetValidator.java index e184f5b93..f9b7989c2 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValueSetValidator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValueSetValidator.java @@ -32,6 +32,7 @@ package org.hl7.fhir.r5.terminologies.validation; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.HashMap; @@ -471,10 +472,12 @@ public class ValueSetValidator { return res; } + private static final HashSet SERVER_SIDE_LIST = new HashSet<>(Arrays.asList("http://fdasis.nlm.nih.gov", "http://hl7.org/fhir/sid/ndc", "http://loinc.org", "http://snomed.info/sct", "http://unitsofmeasure.org", + "http://unstats.un.org/unsd/methods/m49/m49.htm", "http://varnomen.hgvs.org", "http://www.nlm.nih.gov/research/umls/rxnorm", "https://www.usps.com/", + "urn:ietf:bcp:13","urn:ietf:bcp:47","urn:ietf:rfc:3986", "urn:iso:std:iso:3166","urn:iso:std:iso:4217", "urn:oid:1.2.36.1.2001.1005.17")); + private boolean preferServerSide(String system) { - if (Utilities.existsInList(system, "http://fdasis.nlm.nih.gov", "http://hl7.org/fhir/sid/ndc", "http://loinc.org", "http://snomed.info/sct", "http://unitsofmeasure.org", - "http://unstats.un.org/unsd/methods/m49/m49.htm", "http://varnomen.hgvs.org", "http://www.nlm.nih.gov/research/umls/rxnorm", "https://www.usps.com/", - "urn:ietf:bcp:13","urn:ietf:bcp:47","urn:ietf:rfc:3986", "urn:iso:std:iso:3166","urn:iso:std:iso:4217", "urn:oid:1.2.36.1.2001.1005.17")) { + if (SERVER_SIDE_LIST.contains(system)) { return true; } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/BuildExtensions.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/BuildExtensions.java index 529b9fbc4..57ac24c39 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/BuildExtensions.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/BuildExtensions.java @@ -3,7 +3,9 @@ package org.hl7.fhir.r5.utils; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class BuildExtensions extends ToolingExtensions { @@ -51,19 +53,24 @@ public class BuildExtensions extends ToolingExtensions { public static final String EXT_BINDING_NAME = "http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName"; - public static List allConsts() { - List list = new ArrayList<>(); - for (Field field : BuildExtensions.class.getDeclaredFields()) { - int modifiers = field.getModifiers(); - if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) { - try { - list.add(field.get(field.getType()).toString()); - } catch (Exception e) { + private static Set cachedConsts; + + public static Set allConsts() { + if (cachedConsts == null) { + Set list = new HashSet<>(); + for (Field field : BuildExtensions.class.getDeclaredFields()) { + int modifiers = field.getModifiers(); + if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) { + try { + list.add(field.get(field.getType()).toString()); + } catch (Exception e) { + } } } + list.addAll(ToolingExtensions.allConsts()); + cachedConsts = list; } - list.addAll(ToolingExtensions.allConsts()); - return list; + return cachedConsts; } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java index a035ea485..21285e639 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java @@ -68,6 +68,8 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.HashSet; import org.apache.commons.lang3.StringUtils; import org.fhir.ucum.Utilities; @@ -236,8 +238,6 @@ public class ToolingExtensions { public static final String EXT_MAPPING_TGTTYPE = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-target-type"; public static final String EXT_MAPPING_TGTCARD = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-target-cardinality"; - - public static final String WEB_EXTENSION_STYLE = "http://build.fhir.org/ig/FHIR/fhir-tools-ig/format-extensions.html#extension-related-extensions"; public static final String EXT_IGDEP_COMMENT = "http://hl7.org/fhir/tools/StructureDefinition/implementationguide-dependency-comment"; public static final String EXT_XPATH_CONSTRAINT = "http://hl7.org/fhir/4.0/StructureDefinition/extension-ElementDefinition.constraint.xpath"; @@ -1029,20 +1029,23 @@ public class ToolingExtensions { return false; } - public static List allConsts() { - - List list = new ArrayList<>(); - for (Field field : ToolingExtensions.class.getDeclaredFields()) { - int modifiers = field.getModifiers(); - if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) { - try { - list.add(field.get(field.getType()).toString()); - } catch (Exception e) { + private static Set cachedConsts; + + public static Set allConsts() { + if (cachedConsts == null) { + Set list = new HashSet<>(); + for (Field field : ToolingExtensions.class.getDeclaredFields()) { + int modifiers = field.getModifiers(); + if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) { + try { + list.add(field.get(field.getType()).toString()); + } catch (Exception e) { + } } } + cachedConsts = list; } - return list; - + return cachedConsts; } public static boolean hasExtensions(ElementDefinition d, String... urls) { diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java index 0f55f94f2..4a967c6bc 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java @@ -2,6 +2,8 @@ package org.hl7.fhir.utilities; import java.util.ArrayList; import java.util.List; +import java.util.Set; +import java.util.HashSet; import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.exceptions.FHIRException; @@ -393,8 +395,10 @@ public class VersionUtilities { return null; } - public static List getCanonicalResourceNames(String version) { - ArrayList res = new ArrayList(); + + public static Set getCanonicalResourceNames(String version) { + + Set res = new HashSet(); if (isR2Ver(version) || isR2BVer(version)) { res.add("ValueSet"); res.add("ConceptMap"); diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java index c611b5173..2d0be1a81 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java @@ -1031,7 +1031,7 @@ public class BaseValidator implements IValidationContextResourceLoader { if (!Utilities.isAbsoluteUrl(ref)) { String[] p = ref.split("\\/"); List ml = new ArrayList<>(); - if (p.length >= 2 && Utilities.existsInList(p[0], context.getResourceNames()) && Utilities.isValidId(p[1])) { + if (p.length >= 2 && context.getResourceNamesAsSet().contains(p[0]) && Utilities.isValidId(p[1])) { for (int i = 0; i < entries.size(); i++) { Element we = entries.get(i); Element r = we.getNamedChild(RESOURCE); diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java index 72432e446..fb6f6d472 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java @@ -42,6 +42,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Collections; @@ -260,6 +261,29 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat private static final boolean STACK_TRACE = false; private static final boolean DEBUG_ELEMENT = false; + private static final HashSet NO_TX_SYSTEM_EXEMPT = new HashSet<>(Arrays.asList("http://loinc.org", "http://unitsofmeasure.org", "http://hl7.org/fhir/sid/icd-9-cm", "http://snomed.info/sct", "http://www.nlm.nih.gov/research/umls/rxnorm")); + private static final HashSet NO_HTTPS_LIST = new HashSet<>(Arrays.asList("https://loinc.org", "https://unitsofmeasure.org", "https://snomed.info/sct", "https://www.nlm.nih.gov/research/umls/rxnorm")); + private static final HashSet EXTENSION_CONTEXT_LIST = new HashSet<>(Arrays.asList("ElementDefinition.example.value", "ElementDefinition.pattern", "ElementDefinition.fixed")); + private static final HashSet ID_EXEMPT_LIST = new HashSet<>(Arrays.asList("id", "base64Binary", "markdown")); + private static final HashSet HTML_ELEMENTS = new HashSet<>(Arrays.asList( + "p", "br", "div", "h1", "h2", "h3", "h4", "h5", "h6", "a", "span", "b", "em", "i", "strong", + "small", "big", "tt", "small", "dfn", "q", "var", "abbr", "acronym", "cite", "blockquote", "hr", "address", "bdo", "kbd", "q", "sub", "sup", + "ul", "ol", "li", "dl", "dt", "dd", "pre", "table", "caption", "colgroup", "col", "thead", "tr", "tfoot", "tbody", "th", "td", + "code", "samp", "img", "map", "area")); + private static final HashSet HTML_ATTRIBUTES = new HashSet<>(Arrays.asList( + "title", "style", "class", "id", "lang", "xml:lang", "dir", "accesskey", "tabindex", + // tables + "span", "width", "align", "valign", "char", "charoff", "abbr", "axis", "headers", "scope", "rowspan", "colspan")); + + private static final HashSet HTML_COMBO_LIST = new HashSet<>(Arrays.asList( + "a.href", "a.name", "img.src", "img.border", "div.xmlns", "blockquote.cite", "q.cite", + "a.charset", "a.type", "a.name", "a.href", "a.hreflang", "a.rel", "a.rev", "a.shape", "a.coords", "img.src", + "img.alt", "img.longdesc", "img.height", "img.width", "img.usemap", "img.ismap", "map.name", "area.shape", + "area.coords", "area.href", "area.nohref", "area.alt", "table.summary", "table.width", "table.border", + "table.frame", "table.rules", "table.cellspacing", "table.cellpadding", "pre.space", "td.nowrap")); + private static final HashSet HTML_BLOCK_LIST = new HashSet<>(Arrays.asList("div", "blockquote", "table", "ol", "ul", "p")); + private static final HashSet RESOURCE_X_POINTS = new HashSet<>(Arrays.asList("Bundle.entry.resource", "Bundle.entry.response.outcome", "DomainResource.contained", "Parameters.parameter.resource", "Parameters.parameter.part.resource")); + private class ValidatorHostServices implements IEvaluationContext { @Override @@ -1024,7 +1048,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } return false; } - } else if (context.isNoTerminologyServer() && Utilities.existsInList(system, "http://loinc.org", "http://unitsofmeasure.org", "http://hl7.org/fhir/sid/icd-9-cm", "http://snomed.info/sct", "http://www.nlm.nih.gov/research/umls/rxnorm")) { + } else if (context.isNoTerminologyServer() && NO_TX_SYSTEM_EXEMPT.contains(system)) { return true; // no checks in this case } else if (startsWithButIsNot(system, "http://snomed.info/sct", "http://loinc.org", "http://unitsofmeasure.org", "http://www.nlm.nih.gov/research/umls/rxnorm")) { rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_SYSTEM_INVALID, system); @@ -1039,7 +1063,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (system.startsWith("https:") && system.length() > 7) { String ns = "http:"+system.substring(6); CodeSystem cs = getCodeSystem(ns); - if (cs != null || Utilities.existsInList(system, "https://loinc.org", "https://unitsofmeasure.org", "https://snomed.info/sct", "https://www.nlm.nih.gov/research/umls/rxnorm")) { + if (cs != null || NO_HTTPS_LIST.contains(system)) { rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_SYSTEM_HTTPS, system); done = true; } @@ -1868,7 +1892,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } else if (SpecialExtensions.isKnownExtension(url)) { ex = SpecialExtensions.getDefinition(url); - } else if (Utilities.existsInList(url, BuildExtensions.allConsts())) { + } else if (BuildExtensions.allConsts().contains(url)) { // nothing } else if (rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), path, allowUnknownExtension(url), I18nConstants.EXTENSION_EXT_UNKNOWN_NOTHERE, url)) { hint(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), path, isKnownExtension(url), I18nConstants.EXTENSION_EXT_UNKNOWN, url); @@ -1964,7 +1988,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat for (String s : stack.getLogicalPaths()) { String p = stripIndexes(s); // all extensions are always allowed in ElementDefinition.example.value, and in fixed and pattern values. TODO: determine the logical paths from the path stated in the element definition.... - if (Utilities.existsInList(p, "ElementDefinition.example.value", "ElementDefinition.pattern", "ElementDefinition.fixed")) { + if (EXTENSION_CONTEXT_LIST.contains(p)) { return true; } plist.add(p); @@ -2549,9 +2573,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (context.hasPattern()) { ok = checkFixedValue(errors, path, e, context.getPattern(), profile.getVersionedUrl(), context.getSliceName(), null, true) && ok; } - - if (ok && !Utilities.existsInList(e.fhirType(), "id", "base64Binary", "markdown")) { // ids get checked elsewhere + if (ok && !ID_EXEMPT_LIST.contains(e.fhirType())) { // ids get checked elsewhere String regext = FHIRPathExpressionFixer.fixRegex(getRegexFromType(e.fhirType())); if (regext != null) { try { @@ -2757,7 +2780,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (!"url".equals(p[1])) { return false; } - return Utilities.existsInList(p[0], VersionUtilities.getCanonicalResourceNames(context.getVersion())); + return VersionUtilities.getCanonicalResourceNames(context.getVersion()).contains((p[0])); } private boolean containsHtmlTags(String cnt) { @@ -2852,30 +2875,16 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat rule(errors, NO_RULE_DATE, IssueType.INVALID, e.line(), e.col(), path, !node.getContent().startsWith("DOCTYPE"), I18nConstants.XHTML_XHTML_DOCTYPE_ILLEGAL); } if (node.getNodeType() == NodeType.Element) { - rule(errors, NO_RULE_DATE, IssueType.INVALID, e.line(), e.col(), path, Utilities.existsInList(node.getName(), - "p", "br", "div", "h1", "h2", "h3", "h4", "h5", "h6", "a", "span", "b", "em", "i", "strong", - "small", "big", "tt", "small", "dfn", "q", "var", "abbr", "acronym", "cite", "blockquote", "hr", "address", "bdo", "kbd", "q", "sub", "sup", - "ul", "ol", "li", "dl", "dt", "dd", "pre", "table", "caption", "colgroup", "col", "thead", "tr", "tfoot", "tbody", "th", "td", - "code", "samp", "img", "map", "area"), I18nConstants.XHTML_XHTML_ELEMENT_ILLEGAL, node.getName()); + rule(errors, NO_RULE_DATE, IssueType.INVALID, e.line(), e.col(), path, HTML_ELEMENTS.contains(node.getName()), I18nConstants.XHTML_XHTML_ELEMENT_ILLEGAL, node.getName()); for (String an : node.getAttributes().keySet()) { - boolean bok = an.startsWith("xmlns") || Utilities.existsInList(an, - "title", "style", "class", ID, "lang", "xml:lang", "dir", "accesskey", "tabindex", - // tables - "span", "width", "align", "valign", "char", "charoff", "abbr", "axis", "headers", "scope", "rowspan", "colspan") || - - Utilities.existsInList(node.getName() + "." + an, "a.href", "a.name", "img.src", "img.border", "div.xmlns", "blockquote.cite", "q.cite", - "a.charset", "a.type", "a.name", "a.href", "a.hreflang", "a.rel", "a.rev", "a.shape", "a.coords", "img.src", - "img.alt", "img.longdesc", "img.height", "img.width", "img.usemap", "img.ismap", "map.name", "area.shape", - "area.coords", "area.href", "area.nohref", "area.alt", "table.summary", "table.width", "table.border", - "table.frame", "table.rules", "table.cellspacing", "table.cellpadding", "pre.space", "td.nowrap" - ); + boolean bok = an.startsWith("xmlns") || HTML_ATTRIBUTES.contains(an) || HTML_COMBO_LIST.contains(node.getName() + "." + an); if (!bok) { rule(errors, NO_RULE_DATE, IssueType.INVALID, e.line(), e.col(), path, false, I18nConstants.XHTML_XHTML_ATTRIBUTE_ILLEGAL, an, node.getName()); } } - ok = rule(errors, NO_RULE_DATE, IssueType.INVALID, e.line(), e.col(), path, !(inPara && Utilities.existsInList(node.getName(), "div", "blockquote", "table", "ol", "ul", "p")) , I18nConstants.XHTML_XHTML_ELEMENT_ILLEGAL_IN_PARA, node.getName()) && ok; + ok = rule(errors, NO_RULE_DATE, IssueType.INVALID, e.line(), e.col(), path, !(inPara && HTML_BLOCK_LIST.contains(node.getName())) , I18nConstants.XHTML_XHTML_ELEMENT_ILLEGAL_IN_PARA, node.getName()) && ok; ok = checkInnerNames(errors, e, path, node.getChildNodes(), inPara || "p".equals(node.getName())) && ok; } @@ -3291,7 +3300,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat refType = "bundled"; } } - boolean conditional = ref.contains("?") && Utilities.existsInList(ref.substring(0, ref.indexOf("?")), context.getResourceNames()); + boolean conditional = ref.contains("?") && context.getResourceNamesAsSet().contains(ref.substring(0, ref.indexOf("?"))); ReferenceValidationPolicy pol; if (refType.equals("contained") || refType.equals("bundled")) { pol = ReferenceValidationPolicy.CHECK_VALID; @@ -5685,7 +5694,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } private boolean isResourceAndTypes(ElementDefinition ed) { - if (!Utilities.existsInList(ed.getBase().getPath(), "Bundle.entry.resource", "Bundle.entry.response.outcome", "DomainResource.contained", "Parameters.parameter.resource", "Parameters.parameter.part.resource")) { + if (!RESOURCE_X_POINTS.contains(ed.getBase().getPath())) { return false; } for (TypeRefComponent tr : ed.getType()) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java index ebdec7f9f..ebe4c0b7e 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java @@ -1,6 +1,8 @@ package org.hl7.fhir.validation.instance; import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; import org.hl7.fhir.exceptions.FHIRFormatError; import org.hl7.fhir.r5.formats.JsonParser; @@ -18,17 +20,19 @@ public class SpecialExtensions { private static final String CONFORMANCE_DERIVED = "{ \"resourceType\" : \"StructureDefinition\", \"id\" : \"structuredefinition-conformance-derivedFrom\", \"extension\" : [{ \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-wg\", \"valueCode\" : \"fhir\" }, { \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm\", \"valueInteger\" : 1 }], \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-conformance-derivedFrom\", \"version\" : \"4.6.0\", \"name\" : \"fmm\", \"status\" : \"draft\", \"date\" : \"2014-01-31\", \"publisher\" : \"Health Level Seven, Inc. - [WG Name] WG\", \"contact\" : [{ \"telecom\" : [{ \"system\" : \"url\", \"value\" : \"http://hl7.org/special/committees/FHIR\" }] }], \"description\" : \"Indicates one of the resources that was used to infer the specified maturity or standards status\", \"fhirVersion\" : \"4.6.0\", \"mapping\" : [{ \"identity\" : \"rim\", \"uri\" : \"http://hl7.org/v3\", \"name\" : \"RIM Mapping\" }], \"kind\" : \"complex-type\", \"abstract\" : false, \"context\" : [{ \"type\" : \"fhirpath\", \"expression\" : \"extension('http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm').value\" }, { \"type\" : \"fhirpath\", \"expression\" : \"extension('http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status').value\" }], \"type\" : \"Extension\", \"baseDefinition\" : \"http://hl7.org/fhir/StructureDefinition/Extension\", \"derivation\" : \"constraint\", \"snapshot\" : { \"element\" : [{ \"id\" : \"Extension\", \"path\" : \"Extension\", \"short\" : \"FMM Level\", \"definition\" : \"Indicates one of the resources that was used to infer the specified maturity or standards status\", \"min\" : 0, \"max\" : \"*\", \"base\" : { \"path\" : \"Extension\", \"min\" : 0, \"max\" : \"*\" }, \"constraint\" : [{ \"key\" : \"ele-1\", \"severity\" : \"error\", \"human\" : \"All FHIR elements must have a @value or children\", \"expression\" : \"hasValue() or (children().count() > id.count())\", \"xpath\" : \"@value|f:*|h:div\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\" }, { \"key\" : \"ext-1\", \"severity\" : \"error\", \"human\" : \"Must have either extensions or value[x], not both\", \"expression\" : \"extension.exists() != value.exists()\", \"xpath\" : \"exists(f:extension)!=exists(f:*[starts-with(local-name(.), 'value')])\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Extension\" }], \"isModifier\" : false }, { \"id\" : \"Extension.id\", \"path\" : \"Extension.id\", \"representation\" : [\"xmlAttr\"], \"short\" : \"Unique id for inter-element referencing\", \"definition\" : \"Unique id for the element within a resource (for internal references). This may be any string value that does not contain spaces.\", \"min\" : 0, \"max\" : \"1\", \"base\" : { \"path\" : \"Element.id\", \"min\" : 0, \"max\" : \"1\" }, \"type\" : [{ \"extension\" : [{ \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type\", \"valueUrl\" : \"string\" }], \"code\" : \"http://hl7.org/fhirpath/System.String\" }], \"isModifier\" : false, \"isSummary\" : false, \"mapping\" : [{ \"identity\" : \"rim\", \"map\" : \"n/a\" }] }, { \"id\" : \"Extension.extension\", \"path\" : \"Extension.extension\", \"slicing\" : { \"discriminator\" : [{ \"type\" : \"value\", \"path\" : \"url\" }], \"description\" : \"Extensions are always sliced by (at least) url\", \"rules\" : \"open\" }, \"short\" : \"Extension\", \"definition\" : \"An Extension\", \"min\" : 0, \"max\" : \"0\", \"base\" : { \"path\" : \"Element.extension\", \"min\" : 0, \"max\" : \"*\" }, \"type\" : [{ \"code\" : \"Extension\" }], \"constraint\" : [{ \"key\" : \"ele-1\", \"severity\" : \"error\", \"human\" : \"All FHIR elements must have a @value or children\", \"expression\" : \"hasValue() or (children().count() > id.count())\", \"xpath\" : \"@value|f:*|h:div\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\" }, { \"key\" : \"ext-1\", \"severity\" : \"error\", \"human\" : \"Must have either extensions or value[x], not both\", \"expression\" : \"extension.exists() != value.exists()\", \"xpath\" : \"exists(f:extension)!=exists(f:*[starts-with(local-name(.), \\\"value\\\")])\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Extension\" }], \"isModifier\" : false, \"isSummary\" : false }, { \"id\" : \"Extension.url\", \"path\" : \"Extension.url\", \"representation\" : [\"xmlAttr\"], \"short\" : \"identifies the meaning of the extension\", \"definition\" : \"Source of the definition for the extension code - a logical name or a URL.\", \"comment\" : \"The definition may point directly to a computable or human-readable definition of the extensibility codes, or it may be a logical URI as declared in some other specification. The definition SHALL be a URI for the Structure Definition defining the extension.\", \"min\" : 1, \"max\" : \"1\", \"base\" : { \"path\" : \"Extension.url\", \"min\" : 1, \"max\" : \"1\" }, \"type\" : [{ \"extension\" : [{ \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type\", \"valueUrl\" : \"uri\" }], \"code\" : \"http://hl7.org/fhirpath/System.String\" }], \"fixedUri\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-conformance-derivedFrom\", \"isModifier\" : false, \"isSummary\" : false, \"mapping\" : [{ \"identity\" : \"rim\", \"map\" : \"N/A\" }] }, { \"id\" : \"Extension.value[x]\", \"path\" : \"Extension.value[x]\", \"short\" : \"Value of extension\", \"definition\" : \"Value of extension - must be one of a constrained set of the data types (see [Extensibility](extensibility.html) for a list).\", \"min\" : 1, \"max\" : \"1\", \"base\" : { \"path\" : \"Extension.value[x]\", \"min\" : 0, \"max\" : \"1\" }, \"type\" : [{ \"code\" : \"canonical\" }], \"constraint\" : [{ \"key\" : \"ele-1\", \"severity\" : \"error\", \"human\" : \"All FHIR elements must have a @value or children\", \"expression\" : \"hasValue() or (children().count() > id.count())\", \"xpath\" : \"@value|f:*|h:div\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\" }], \"isModifier\" : false, \"isSummary\" : false, \"mapping\" : [{ \"identity\" : \"rim\", \"map\" : \"N/A\" }] }] }, \"differential\" : { \"element\" : [{ \"id\" : \"Extension\", \"path\" : \"Extension\", \"short\" : \"FMM Level\", \"definition\" : \"Indicates one of the resources that was used to infer the specified maturity or standards status\", \"min\" : 0, \"max\" : \"*\" }, { \"id\" : \"Extension.extension\", \"path\" : \"Extension.extension\", \"max\" : \"0\" }, { \"id\" : \"Extension.url\", \"path\" : \"Extension.url\", \"fixedUri\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-conformance-derivedFrom\" }, { \"id\" : \"Extension.value[x]\", \"path\" : \"Extension.value[x]\", \"min\" : 1, \"type\" : [{ \"code\" : \"canonical\" }] }] } }"; private static final String FMM_SUPPORT = "{ \"resourceType\" : \"StructureDefinition\", \"id\" : \"structuredefinition-fmm-support\", \"extension\" : [{ \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-wg\", \"valueCode\" : \"fhir\" }, { \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm\", \"valueInteger\" : 1 }], \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm-support\", \"version\" : \"4.6.0\", \"name\" : \"fmm\", \"status\" : \"draft\", \"date\" : \"2014-01-31\", \"publisher\" : \"Health Level Seven, Inc. - [WG Name] WG\", \"contact\" : [{ \"telecom\" : [{ \"system\" : \"url\", \"value\" : \"http://hl7.org/special/committees/FHIR\" }] }], \"description\" : \"The documentation supporting the FMM level assigned to the artifact.\", \"fhirVersion\" : \"4.6.0\", \"mapping\" : [{ \"identity\" : \"rim\", \"uri\" : \"http://hl7.org/v3\", \"name\" : \"RIM Mapping\" }], \"kind\" : \"complex-type\", \"abstract\" : false, \"context\" : [{ \"type\" : \"element\", \"expression\" : \"Element\" }], \"type\" : \"Extension\", \"baseDefinition\" : \"http://hl7.org/fhir/StructureDefinition/Extension\", \"derivation\" : \"constraint\", \"snapshot\" : { \"element\" : [{ \"id\" : \"Extension\", \"path\" : \"Extension\", \"short\" : \"FMM Level\", \"definition\" : \"The documentation supporting the FMM level assigned to the artifact.\", \"comment\" : \"Though this is defined for resources, it can be used for any artifact.\", \"min\" : 0, \"max\" : \"1\", \"base\" : { \"path\" : \"Extension\", \"min\" : 0, \"max\" : \"*\" }, \"constraint\" : [{ \"key\" : \"ele-1\", \"severity\" : \"error\", \"human\" : \"All FHIR elements must have a @value or children\", \"expression\" : \"hasValue() or (children().count() > id.count())\", \"xpath\" : \"@value|f:*|h:div\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\" }, { \"key\" : \"ext-1\", \"severity\" : \"error\", \"human\" : \"Must have either extensions or value[x], not both\", \"expression\" : \"extension.exists() != value.exists()\", \"xpath\" : \"exists(f:extension)!=exists(f:*[starts-with(local-name(.), 'value')])\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Extension\" }], \"isModifier\" : false }, { \"id\" : \"Extension.id\", \"path\" : \"Extension.id\", \"representation\" : [\"xmlAttr\"], \"short\" : \"Unique id for inter-element referencing\", \"definition\" : \"Unique id for the element within a resource (for internal references). This may be any string value that does not contain spaces.\", \"min\" : 0, \"max\" : \"1\", \"base\" : { \"path\" : \"Element.id\", \"min\" : 0, \"max\" : \"1\" }, \"type\" : [{ \"extension\" : [{ \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type\", \"valueUrl\" : \"string\" }], \"code\" : \"http://hl7.org/fhirpath/System.String\" }], \"isModifier\" : false, \"isSummary\" : false, \"mapping\" : [{ \"identity\" : \"rim\", \"map\" : \"n/a\" }] }, { \"id\" : \"Extension.extension\", \"path\" : \"Extension.extension\", \"slicing\" : { \"discriminator\" : [{ \"type\" : \"value\", \"path\" : \"url\" }], \"description\" : \"Extensions are always sliced by (at least) url\", \"rules\" : \"open\" }, \"short\" : \"Extension\", \"definition\" : \"An Extension\", \"min\" : 0, \"max\" : \"0\", \"base\" : { \"path\" : \"Element.extension\", \"min\" : 0, \"max\" : \"*\" }, \"type\" : [{ \"code\" : \"Extension\" }], \"constraint\" : [{ \"key\" : \"ele-1\", \"severity\" : \"error\", \"human\" : \"All FHIR elements must have a @value or children\", \"expression\" : \"hasValue() or (children().count() > id.count())\", \"xpath\" : \"@value|f:*|h:div\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\" }, { \"key\" : \"ext-1\", \"severity\" : \"error\", \"human\" : \"Must have either extensions or value[x], not both\", \"expression\" : \"extension.exists() != value.exists()\", \"xpath\" : \"exists(f:extension)!=exists(f:*[starts-with(local-name(.), \\\"value\\\")])\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Extension\" }], \"isModifier\" : false, \"isSummary\" : false }, { \"id\" : \"Extension.url\", \"path\" : \"Extension.url\", \"representation\" : [\"xmlAttr\"], \"short\" : \"identifies the meaning of the extension\", \"definition\" : \"Source of the definition for the extension code - a logical name or a URL.\", \"comment\" : \"The definition may point directly to a computable or human-readable definition of the extensibility codes, or it may be a logical URI as declared in some other specification. The definition SHALL be a URI for the Structure Definition defining the extension.\", \"min\" : 1, \"max\" : \"1\", \"base\" : { \"path\" : \"Extension.url\", \"min\" : 1, \"max\" : \"1\" }, \"type\" : [{ \"extension\" : [{ \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type\", \"valueUrl\" : \"uri\" }], \"code\" : \"http://hl7.org/fhirpath/System.String\" }], \"fixedUri\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm-support\", \"isModifier\" : false, \"isSummary\" : false, \"mapping\" : [{ \"identity\" : \"rim\", \"map\" : \"N/A\" }] }, { \"id\" : \"Extension.value[x]\", \"path\" : \"Extension.value[x]\", \"short\" : \"Value of extension\", \"definition\" : \"Value of extension - must be one of a constrained set of the data types (see [Extensibility](extensibility.html) for a list).\", \"min\" : 1, \"max\" : \"1\", \"base\" : { \"path\" : \"Extension.value[x]\", \"min\" : 0, \"max\" : \"1\" }, \"type\" : [{ \"code\" : \"markdown\" }], \"constraint\" : [{ \"key\" : \"ele-1\", \"severity\" : \"error\", \"human\" : \"All FHIR elements must have a @value or children\", \"expression\" : \"hasValue() or (children().count() > id.count())\", \"xpath\" : \"@value|f:*|h:div\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\" }], \"isModifier\" : false, \"isSummary\" : false, \"mapping\" : [{ \"identity\" : \"rim\", \"map\" : \"N/A\" }] }] }, \"differential\" : { \"element\" : [{ \"id\" : \"Extension\", \"path\" : \"Extension\", \"short\" : \"FMM Level\", \"definition\" : \"The documentation supporting the FMM level assigned to the artifact.\", \"comment\" : \"Though this is defined for resources, it can be used for any artifact.\", \"min\" : 0, \"max\" : \"1\" }, { \"id\" : \"Extension.extension\", \"path\" : \"Extension.extension\", \"max\" : \"0\" }, { \"id\" : \"Extension.url\", \"path\" : \"Extension.url\", \"fixedUri\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm-support\" }, { \"id\" : \"Extension.value[x]\", \"path\" : \"Extension.value[x]\", \"min\" : 1, \"type\" : [{ \"code\" : \"markdown\" }] }] } }"; + private static final HashSet KNOWN_EXTENSIONS = new HashSet<>(Arrays.asList( + "http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support", + "http://hl7.org/fhir/StructureDefinition/instance-name", + "http://hl7.org/fhir/StructureDefinition/instance-description", + "http://hl7.org/fhir/build/StructureDefinition/definition", // wrongly defined in used in early R4B/R5 builds - changed to http://hl7.org/build/fhir/StructureDefinition/binding-definition + "http://hl7.org/fhir/StructureDefinition/codesystem-properties-mode", + "http://hl7.org/fhir/StructureDefinition/structuredefinition-rdf-type", + "http://hl7.org/fhir/StructureDefinition/structuredefinition-conformance-derivedFrom", // this is defined in R5, but needed earlier + "http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm-support" // this is defined in R5, but needed earlier + )); + public static boolean isKnownExtension(String url) { - return Utilities.existsInList(url, - "http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support", - "http://hl7.org/fhir/StructureDefinition/instance-name", - "http://hl7.org/fhir/StructureDefinition/instance-description", - "http://hl7.org/fhir/build/StructureDefinition/definition", // wrongly defined in used in early R4B/R5 builds - changed to http://hl7.org/build/fhir/StructureDefinition/binding-definition - "http://hl7.org/fhir/StructureDefinition/codesystem-properties-mode", - "http://hl7.org/fhir/StructureDefinition/structuredefinition-rdf-type", - "http://hl7.org/fhir/StructureDefinition/structuredefinition-conformance-derivedFrom", // this is defined in R5, but needed earlier - "http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm-support" // this is defined in R5, but needed earlier - ); + return KNOWN_EXTENSIONS.contains(url); } public static StructureDefinition getDefinition(String url) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java index 9206557a2..c7eab1f83 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java @@ -1060,7 +1060,7 @@ public class StructureMapValidator extends BaseValidator { if (sdt == null) { throw new Error("Unable to resolve "+url); } else { - ElementDefinition t2 = sdt.getSnapshot().getElementByPath(path); + ElementDefinition t2 = sdt.getSnapshot().getElementByPath(path, true); if (t2 == null) { throw new Error("Unable to resolve "+path+" in "+url); } else {